Dine89 Geschrieben 21. Oktober 2010 Geschrieben 21. Oktober 2010 Hallo ihr, ich hoffe ihr könnt mir helfen. Ich sitze an meinem Abschlussprojekt für die IHK Prüfung. Ich mache meine Ausbildung zur Fachinformatikerin AE. Mein Problem ist, dass ich ein Programm schreiben soll, dass mehrere Strings aus einer Liste einliest und diese Strings dann in Dateien suchen soll. Die Dateien, die durchsucht werden sollen, dass sind tausende. Ich habe auch schon eine Suchfunktion erstellt, die funktioniert soweit auch, aber die dauert viiiieeeel zu lange. import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Vector; import javax.swing.JRadioButton; import javax.swing.JTextField; public class Search { // Attribute Vector v2; String suchordner; BufferedWriter writer; BufferedWriter helpWriter; String wordToFind; boolean append; String outputFile; int i = 0; String qryCopy; String hitordner; String dest; // Konstruktor public Search(Vector v2, String ordner, String qryCopy, String hitordner) { // TODO Auto-generated constructor stub this.v2 = v2; this.suchordner = ordner; this.qryCopy = qryCopy; this.hitordner = hitordner; outputFile = "log.txt"; try { //System.out.println( j + ": " + v2.elementAt(j) ); startScanning(new File(ordner), v2, outputFile, i); i++; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } Output out = new Output(); } public void startScanning(File dir, Vector v2, String outputFile, int i) throws IOException{ this.wordToFind = wordToFind; try { // writer für LogDatei writer = new BufferedWriter(new FileWriter(outputFile, true)); //writer für Hilfsfile helpWriter = new BufferedWriter(new FileWriter("help.txt", true)); // Schreiben in LogDatei if(i == 0){ SimpleDateFormat formatter = new SimpleDateFormat ("dd.MM.yyyy 'at' HH:mm:ss "); Date currentTime = new Date(); writer = new BufferedWriter(new FileWriter(outputFile, true)); writer.append("~~~~~~~~Suchvorgang: " + formatter.format(currentTime) + "~~~~~~~~"); writer.newLine(); writer.newLine(); } readDir(dir); } finally{ if(writer!= null) try { writer.close(); } catch (IOException e) { } if(helpWriter!= null) try { helpWriter.close(); } catch (IOException e) { } } } // Auflisten der Files public void readDir(File dir) throws IOException{ if(dir.isDirectory()){ File[] files = dir.listFiles(); for(File file: files){ System.out.println(file.getName()); readDir(file); } }else{ readInFile(dir); } } // Durchsuchen der Dateien public void readInFile(File file) throws IOException{ BufferedReader reader =null; try { for ( int j=0; j < v2.size(); j++ ){ wordToFind = (String) v2.elementAt(j); reader = new BufferedReader(new FileReader(file)); String line = null; int lineNumber =0; boolean found = false; while((line= reader.readLine()) !=null) { lineNumber++; if(line.contains(wordToFind)){ if(!found) { // Schreiben in LogDatei writer.append(file.getAbsolutePath()+":\r\n"); writer.newLine(); // Schreiben in Hilfsdatei helpWriter.append(file.getAbsolutePath()+":\r\n"); helpWriter.newLine(); if(qryCopy == "OK"){ dest = hitordner + "\\" + file.getName(); Copy kopieren = new Copy(file.getAbsolutePath(), dest); } found = true; } try { // Schreiben in LogDatei writer.append(lineNumber+": "+line+"\r\n"); writer.newLine(); // Schreiben in Hilfsdatei helpWriter.append(lineNumber+": "+line+"\r\n"); helpWriter.newLine(); } catch (IOException e) { System.out.println("Fehler beim Schreiben!!"); e.printStackTrace(); } } } } }finally{ reader.close(); } } } Ich hoffe es ist verständlich,was ich hier mache. Die Strings, die in den Dateien gesucht werden müssen, habe ich vorher in einem Vector geschrieben. Habt ihr vllt eine schnellere Lösung? Ich habe schon überall gesucht, aber ich finde einfach ncihts. Zitieren
flashpixx Geschrieben 21. Oktober 2010 Geschrieben 21. Oktober 2010 Habt ihr vllt eine schnellere Lösung? Ich habe schon überall gesucht, aber ich finde einfach ncihts. Da es sich um Logdateien handelt würde ich zu regulären Ausdrücken greifen. Aber Vorsicht so etwas kann unter Umständen sehr ineffizient bei großen Datenmengen werden, deshalb würde ich zu Multithreading greifen und ggf das ganze durch eine Datenbank sinnvoll indizieren, wobei je nach Datenbank hier auch direkt Textprocessing-Ansätze zur Verfügung gestellt werden Zitieren
etreu Geschrieben 21. Oktober 2010 Geschrieben 21. Oktober 2010 Ist die Programmiersprache vorgegeben oder kannst du sie noch Wechseln? Wird die Suche einmalig auf den Daten gemacht oder wiederholt? Zitieren
Dine89 Geschrieben 21. Oktober 2010 Autor Geschrieben 21. Oktober 2010 Ich kann die Sprache nicht mehr wechseln... Schon alleine, weil eine andere Sprache hier nicht gewartet werden kann, wenn ich nciht mehr hier bin. Wobei cih für das Warten meinen Code auch noch verschönern muss Also das Hauptproblem bei dieser Anwendung ist, dass ich ein Vector mit den Suchbegriffen habe und der BufferedReader sucht ja Line-weise und dann geht er für jede Line in jeder Datei das Array wieder ab. Und das dauert ewig... Gibt es dafür noch eine andere Möglichkiet? Hier ist mal ein Ausschnitt aus der Problemzone, ich habe den Code etwas verändert, was das durchgehen des Vectors angeht, der ist jetzt an einer anderen Stelle: while((line= reader.readLine()) !=null) { lineNumber++; for ( int j=0; j < v2.size(); j++ ){ <-- An dieser stelle liegt das Hauptproblem wordToFind = (String) v2.elementAt(j); if(line.contains(wordToFind)){ if(!found) { // Schreiben in LogDatei writer.append(file.getAbsolutePath()+":\r\n"); writer.newLine(); ...... Zitieren
flashpixx Geschrieben 21. Oktober 2010 Geschrieben 21. Oktober 2010 Also das Hauptproblem bei dieser Anwendung ist, dass ich ein Vector mit den Suchbegriffen habe und der BufferedReader sucht ja Line-weise und dann geht er für jede Line in jeder Datei das Array wieder ab. Und das dauert ewig... Gibt es dafür noch eine andere Möglichkiet? Ich würde je nach Datenmenge ein völlig anderes Vorgehen verwenden. Ersteinmal sinnvolles Crawlen der Daten, so dass ich einen passenden Index aufbaue. Je nachdem lässt sich auch die Dokumente entsprechend direkt indizieren (term frequency / inverse document frequency). Zusätzlich kommen Dimension Reduction Techniken, um die Datenmenge zu reduzieren. Direktes Matching ist eben völlig ineffizient für große Datenmenge. So wie Du das machst, wird es nicht funktionieren Zitieren
etreu Geschrieben 21. Oktober 2010 Geschrieben 21. Oktober 2010 Du kannst aus deiner Wertliste ein Muster für regex bauen. Dann wäre das pro Zeile nur ein Vergleich. Bsp: aus {'A','B','C'} wird "(A)|(|©" Zitieren
flashpixx Geschrieben 21. Oktober 2010 Geschrieben 21. Oktober 2010 Du kannst aus deiner Wertliste ein Muster für regex bauen. Dann wäre das pro Zeile nur ein Vergleich. Funktioniert aber nicht mit Flexionen oder Fehlern in den Texten, da ein exaktes Matching erwartet wird. Außerdem ist das für viele Dokumente, die relativ groß sind, immer noch absolut ineffizient Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.