Textdatei einlesen und darin suchen

Doc

Aktives Mitglied
Hallo,
ich bin neu hier Forum, daher erst mal einen Gruß an alle ;-)
Ich bin mit Java nicht besonders erfahren und arbeite gerade an einem kleinen Programm.
Da ich niemand habe, um kleine Problemchen zu besprechen läuft vieles auf try-and-error hinaus.
Ich hab schon relativ viel Zeit investiert mich in Foren einzulesen und Hilfe zu bekommen.
Leider bin ich bisher nicht erfoglreich gewesen.
Daher würde ich mich freuen, wenn ich hier etwas Hilfe bekommen könnte.

Zu meinem Programm:
Ich möchte ein kleines Programm schreiben, das eine Textdatei einliesst.
Danach möchte ich in diesem Text nach Wörtern suchen.

Meine bisherige Idee war, die Datei mit FileReader einzulesen.
Danach wollte ich die Datei mit BufferedReader in einen String zeilenweise einlesen, und danach diesen String durchsuchen.
Ist diese Vorgehensweise grundsätzlich in Ordnung oder gibt es bessere Möglichkeiten?
Kann ich auch die eingelesene Datei direkt durchsuchen? Oder muss das ganze über einen String laufen? Und wenn ja, kann ich die Datei auch Direkt in einen String einlesen (anstatt zeilenweise)?

Hier nun mein bisheriges Programm:

Java:
File datei = new File("Text.txt");
FileReader fr = new FileReader(datei);
BufferedReader br = new BufferedReader(fr); 

String str;	
	
while ((str = br.readLine()) != null) {

	//Hier würde ich gerne zeilenweise aus dem BufferedReader in einen String schreiben,
	//bis die gesamte Textdatei in einem großen String liegt. Der Gedanke war den String str an
	//einen großen String anzuhängen, der nacher den gesamten Text enthält.
	//Leider bisher ohne Erfolg. Wie lässt sich das bewerkstelligen?
	
}

br.close(); 
				
if (text.contains("Wort")){
	System.out.println("gefunden");
}



Vielen Dank im Voraus für die Hilfe.

Grüße,
Doc
 
Zuletzt bearbeitet:
Gruß auch an dich 🙂

Zu deinem Problem: Du kannst in deiner while-Schleife tatsächlich einfach immer wieder die soeben eingelesene Zeile an einen "Sammelstring" dranhängen (formal ist es, soweit ich weiß, zwar immer ein neuer String, der da erstellt wird, aber so ist es anschaulicher). Zum Beispiel so:
Java:
String str = "";
while(true) {
	String in = br.readLine();
	if(in == null) break;
	str = str + in;
}

Die Deklarationen der einzelnen Reader kannst du übrigens auch in einem Aufwasch machen:
Java:
BufferedReader br = new BufferedReader(new FileReader(f)); //f ist ein Objekt der Klasse File
 
Du könntest die einzelnen Wörter auch in eine ArrayList (oder in eine Hashmap packen, wenn sie nicht doppelt vorkommen sollen) und dann diese durchsuchen. Die Sache mit dem String(in Kombination mit einem StringTokenizer) war zumindest bei mir bei größeren Texten unheimlich langsam. Kann aber auch daran liegen, dass ich es dumm angegangen bin...
 
vielen dank! jetzt funktioniert es.

falls jemand noch eine bessere möglichkeit einfällt, würde ich mich über hilfe freuen.
vielleicht gibt es ja noch eine bessere möglichkeit für dieses problem.

danke nochmals!
 
ich habs jetzt mit deinem tipp gelöst.

aber mir kommt es etwas umständlich vor den string zeilenweise zu füllen. gibts es nicht die möglichkeit, die textdatei auf einmal in einen string zu schreiben?
 
Mir wäre da spontan keine andere Möglichkeit einfallen. Ich habe solche Dinge bisher mit BufferedReadern, ObjectInputReadern, FileInputStreams oder Scannern gelöst - alle machen das schrittweise, wenn nicht sogar alle in Zeilen. Du kannst Dir stattdessen ja auch eine Pseudo-Methode schreiben, welche eine Datei zeilenweise einliest und dann einen kompletten String zurückgibt.
 
String in einer Schleife zu konkatenieren ist für den Anfang nicht schlimm, aber falls die Datei mal größer wird,
ist es ein Performance-Grab.


Probier es selber:
Java:
public class StringTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{
		int times = 100000;
		String val = "Hallo";
		System.out.println("StringBuilder: " + buildString(times, val));
		System.out.println("String concatination: " + concatString(times, val));
		
	}
	
	public static long concatString(int times, String val)
	{
		String localVal = "";
		long start = System.currentTimeMillis();	
		for(int i=0;i<times;i++)
		{
			localVal = localVal + val;
		}
		long stop = System.currentTimeMillis();
		
		return stop - start;
	}
	
	public static long buildString(int times, String val)
	{
		StringBuilder localVal = new StringBuilder();
		long start = System.currentTimeMillis();	
		for(int i=0;i<times;i++)
		{
			localVal.append(val);
		}
		long stop = System.currentTimeMillis();
		
		return stop - start;
	}

}
 
Ungetestet:
Java:
Scanner sc=new Scanner(
	new BufferedInputStream(
		new FileInputStream(
			new File("/tmp/irgendwo")
		)
	),
	"UTF-8" // alternativ anderer Zeichensatz oder Standardzeichensatz
);

// TODO hier scannen

sc.close();
Ark
 
hallo,
danke für eure antworten, aber leider ist mir nicht ganz klar, was ihr mir das gepostet habt.
ich bin wie gesagt nicht sehr erfahren mit java.

@nroz:
ich vermmute es handelt sich um einen perfomance test mit timestamps?

@ark:
was du mir gezeigt hast, versteh ich leider nicht.


leider benötige ich das programm für größere texte. wie könnte ich das problem denn anders lösen?

danke für eure hilfe.
 
Wenn du einen großen String durch + immer wieder ergänzt/Werte hinzufügst wird das irgendwann sehr langsam.
Um dem zu umgehen solltest du die Klasse StringBuilder verwenden und jede neue Zeile mit append() hinzufügen.

Sobald du dann mit dem String arbeiten willst kannst du die toString()-Methode verwenden.

Java:
	public FileWorker()
	{
		File file = null;
		FileReader fr = null;
		BufferedReader br = null;
		try
		{
			file = new File("myFile.txt");
			fr = new FileReader(file);
			br = new BufferedReader(fr);
			
			StringBuilder sb = new StringBuilder();
			String line;
			while((line = br.readLine()) != null)
			{
				sb.append(line);
				// Zeilenumbruch falls gewünscht, ansonsten die nächste Zeile auskommentieren.
				sb.append("\n");
			}
			
			System.out.println(sb.toString());
			
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				br.close();
				fr.close();
			}
			catch (IOException e)
			{
				// do nothing on exception
			}
		}
	}
 
Zuletzt bearbeitet:

Zurück
Oben