String einlesen, in .txt durchsuchen und Ergebnisse ausgeben

houlyy

Mitglied
Hallo zusammen,

ich wollte gern ein kleines app mit GUI schreiben.
Im Textfeld wird eine 7-stellige Nummer eingegeben und es soll gesucht werden, ob diese sich in der Textdatei befindet. Es wäre günstig wenn er danach:

a) anzeigt das die Nummer vorhanden ist ODER
b) wenn er die ganze Zeile aus der Textdatei ausgibt in einer Textarea

Leider habe ich noch nicht soviel programmiert, aber hab mal angefangen etwas. Es fehlt aber glaube auch noch eine Schleife, denn er zeigt in der Textarea bisher nur einmal was an.

Mein Code bisher:

Java:
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        
        try {
		BufferedReader in = new BufferedReader(new FileReader("C:\\archiv.txt"));
		String zeile;
		while ((zeile = in.readLine()) != null) {
                    {
                       zeile = in.readLine();
                       if(eingabe.equals(zeile)){
                           jTextArea1.setText(zeile);
                           //jTextArea1.setText("Eintrag gefunden");
                        }else{
                        }
                        jTextArea1.setText("Kein Eintrag gefunden");
                    }
		}
	} catch (IOException e) {
		e.printStackTrace();
	}
    }

cpq6vt8z.jpg
 
Der Anfang ist gar nicht so schlecht.

Hättest du dir aber die API Doku von readLine() angeschaut wüsstest du, dass du den Aufruf nur einmal pro Durchgang machen musst.

Java:
  try {
        BufferedReader in = new BufferedReader(new FileReader("C:\\archiv.txt"));
        String zeile;
String code= txtFieldCode.getText();
        while ((zeile = in.readLine()) != null) {
                    {
                 
                       if(zeile.equals(code)){
                           jTextArea1.setText(zeile);
                           //jTextArea1.setText("Eintrag gefunden");
                        }else{
                        }
                        jTextArea1.setText("Kein Eintrag gefunden");
                    }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

Nach meiner Sicht ist an der Stelle auch eine Datenbank in betracht zu ziehen.
 
Hallo,

danke für die Antwort.
Leider funktioniert es dennoch nicht. Egal welche Zeile ich suche, er gibt nur aus "Kein Eintrag gefunden". Und was ich jetzt noch nicht ganz verstanden habe...wie mache ich es, dass ich unedlich oft weitersuchen kann, ohne das Programm neuzustarten?

Edit: Also die erneute Suche geht glaube ich. Man merkt es nur nicht, da er immer wieder "Kein Eintrag gefunden" anzeigt.

Was fehlt noch, damit der die .txt richtig durchsucht und ausgibt :roll:

Viele Grüße
 
Zuletzt bearbeitet:
Naja ein bisschen Überlegen sollst du schon noch.
Java:
 jTextArea1.setText("Kein Eintrag gefunden");

Muss in das else{}
Sonst schreibt er das immer auch wenn die Bedingung true ist.
Deine andere Frage verstehe ich nicht. Du rufst die Methode doch auf Button Click auf oder? Die wird immer ausgeführt, wenn du auf den Button klickst. Das textField hat ein OnChange Event. Das heißt immer wenn der Text geändert wird, wird diese Methode aufgerufen. Aber da kannst du ruhig mal google Fragen. Wird bestimmt schon 100000 mal beantwortet.
 
Sorry, das hab ich total übersehen das die Zeile außerhalb des else ist...
Es wird aber dennoch immer nur die letzte Zeile in der Textdatei gefunden und als "Eintrag gefunden" angezeigt. Ist es möglich das er alle Zeilen überprüft?

Die letzte Frage hatte sich eigentlich erübrigt.
 
Zuletzt bearbeitet:
Java:
                       if(zeile.equals(code)){

Das impliziert, dass zeile == code sein muss.

Wenn eine Zeile aber aus z.B" Code - irgendein Text" besteht, liefert equals false.

Die Methode die du suchst heißt contains().

Edit: Schließe den Reader mit close() am ende der Methode.
 
Zuletzt bearbeitet:
Langsam rafft es mein Kopf 😉 Ich hab natürlich nur genau das verglichen was ich im Textfeld eingebe und nicht den Teil einer ganzen Zeichenkette. Trotzdem bin ich zu blöd, dass er alle Zeilen durchsucht 🙁 Nur bei der letzten Zeile gibt er true zurück. Bei anderen aus der Textdatei nicht.

Muss ich den BufferedReader UND den FileReader schließen? Und schließt man den dann im try Block?
 
Zuletzt bearbeitet:
Eigentlich sollte man so etwas schreiben:

Java:
	try {
			
		} catch (Exception e) {
			// TODO: handle exception
		}finally{
			//Close all streams 
		}

Ich verstehe jedoch nicht ganz was nicht funktioniert? Kannst du nochmal dein Code posten und einen Auszug aus deiner .txt Datei und Angeben was er findet und was nicht?
 
Java:
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        
        try {
		BufferedReader in = new BufferedReader(new FileReader("C:\\archiv.txt"));
		String zeile;
                String code = jTextField1.getText();
            if(jTextField1.getText().length() == 0){
                jTextArea1.setText("Keine Nummer eingegeben");
            }
            else{
                while ((zeile = in.readLine()) != null) {
                    {
                       if(zeile.contains(code)){
                           jTextArea1.setText(zeile);
                           jTextArea1.setText("Eintrag" + " " +code+ " " + "gefunden");
                        }else{
                           jTextArea1.setText("Kein Eintrag gefunden");
                        }  
                    }
		 }

              }
           in.close();
	} catch (IOException e) {
		e.printStackTrace();
        }
    }

In der Textdatei sind ein paar Zahlenkombinationen drinne:

Code:
123456
3242423
323
4242424
231324

Suche ich im Programm nach 123456, dann sagt er kein Eintrag gefunden.
Wenn man aber nach 231324 (letzter Eintrag) in der Textdatei sucht, dann findet er diese und sagt "Eintrag gefunden".
 
Mach dir vor dem If ein system.out.println von Zeile, lass dir anzeigen was genau er gerade für eine Zeile bearbeitet.
Dann in dem If und in dem else auch ein println mit den jeweils interessanten Werten. Dann siehst du genau was er macht und wo es falsch läuft.
 
@MiMij sowas kann man relativ gut auch im Debugger sehen.

Aber back to topic

Java ist eine objektorientierte Sprache. Verwende sie auch so.

Java:
public class CodeControll {

	private Set<String> codes;

	public CodeControll(File file) throws IOException {
		//ließt das angegebene File in ein Hashset Line by Line
		codes = new HashSet<String>(Files.readAllLines(file.toPath(), Charset.defaultCharset()));
	}

	
	/**
	 * returnt true wenn der gegebene Code in dem Set vorhanden ist
	 * @param code
	 * @return
	 */
	public boolean hasCode(String code) {
		return codes.contains(code);
	}

	/**
	 * returnt true wenn der gegebene Code in einem String vom Set enthalten ist
	 */
	
	public boolean containsCode(String code) {
		for (String currCode : codes) {
			if (currCode.contains(code)) {
				return true;
			}
		}
		return false;
	}

}

So würde ich das ganze ungefähr machen. Deine View (Gui Klasse" ruft einfach nur containsCode mit dem entsprechendem Parameter auf und die Sache hat sich. Am Anfang wird das komplette File in ein Set geladen. Das hat den Vorteil es ist im Speicher vorhanden, schnelle Zugriffzeiten und man muss nicht ständig ein neues Streamobjekt erstellen. Schreibzugriffe werden so allerdings schwierig.
 
Danke für die Hilfe!
Schreibzugriffe auf die Textfile sind nicht notwenig.

Jetzt hab ich aber durch die Änderung schon wieder 0 Peilung was in der View geändert werden muss. Könntest du mir dort noch behilflich sein?
 
@MiMij sowas kann man relativ gut auch im Debugger sehen.

Das ist mir klar, aber viele Anfänger und auch einige Fortgeschrittene, haben Probleme mit dem Debugger, wie man ihn nutzen muss, deswegen empfehle ich meist das println.




@houlyy
Hast du das mal probiert mit den Ausgaben? Versteh erstmal deinen Code bevor du von anderen einfach was kopierst.
 
Ich hab bisher alles verstanden was geändert wurde, aber jetzt nicht mehr so richtig.

In der CodeControll Klasse verstehe ich z.B. nicht wo definiert ist, dass er die .txt als HashSet String einliest??
 
Du hast deinen Code nicht verstanden, warum er nur die letzte Zeile findet. Deswegen hatte ich dir als TIpp gegeben mal ein paar Sytem.out.println einzufügen um zu sehen was genau konotrolliert wird.
 
Seit Java 7 gibt es die Utility Klasse Files. Die bietet eine Methode an

readAllLines(Path path, Charset charset);

Diese lädt Zeile für Zeile in eine ArrayList. Aus Faulheit füge ich den Inhalt der List einem Set hinzu um besser auf die Elemente zugreiffen zu können. Außerdem ist ein Set bei vielen Elementen schneller (im Sinn von suchen & finde) wobei das bei deinem Szenario wahrscheinlich irrelevant ist.

Java:
  codes = new HashSet<String>(Files.readAllLines(file.toPath(), Charset.defaultCharset()));
 
Zuletzt bearbeitet:
Die einzelnen Codeausschnitte habe ich im groben schon verstanden.
Wird die Methode containsCode jetzt einfach nur durch den String Zeile aus der View ersetzt oder wird der ganze BufferedReader ersetzt?

Komme dort noch nicht ganz klar, wie die neue Klasse in der View zum Einsatz kommt.
 
Um, schau dir mal ein Tut an zu Java und OOP.

Java:
private CodeControll codeControll = new CodeControll(new File("somePAth")); //erstellt eine neues Objekt der Klasse CodeControll



//später im Code

if(codeControll.containsCode(txtView.getText())){
//do something
}else{
//do something else
}
 
Das ist zwar echt peinlich, aber ich hatte das alles schon^^
Hab Inofmratik Master und genug OOP, nur hab ich danach nie wieder programmiert oder es gebraucht...wenn man nicht täglich/wöchentlich mal was macht, vergisst man das ganz schnell.

Da geht schon los, wenn man wieder überlegt wie man eine Methode einer anderen Klasse aufruft. Eine Instanz der Klasse anzulegen war für mein Kopf schon wieder zuviel wohl 😛
 
Ich hab noch ein Problem festgestellt.
Wenn in der Textdatei zuviele Einträge sind gibt er nix aus. Es kommt folgender Fehler:

Code:
java.nio.charset.MalformedInputException: Input length = 1

So wie ich das mitbekommen hab, kommt der Fehler durch einen illegalen Character.
Kann man das umgehen?
 
Was heißt zu viele Einträge? Schau mal die Methode readAllLines hat einen Parameter names Charset. Dort kannst du versuchen einen anderen Anzugeben. Momentan nimmt er den default charset. Keine Ahnung was das bei Windows ist. Versuche einfach mal UTF-8 oder so.
 
Hab verschiedene ausprobiert, aber entweder kommt eine Exception oder er hängt ewig und sucht. Bei einer Textdatei mit 10 Zeilen geht es ohne Probleme, aber bei einer Textdatei mit 85.000 Zeilen mit einer Größe von fast 5MB geht es leider nicht.
 
Er gibt dir auch immer nur Eintrag gefunden aus wenn der Eintrag der letzte war, weil du dein JTextField Inhalt immer überschreibst. Anstatt
Java:
textField.setText("");
schreib doch mal
Java:
textField.setText(textField.getText()+"");

Zum zweiten blockiert er natürlich bei so vielen Zeilen. Mach das Laden/durchsuchen doch asynchron und lager das ganze in eine Worker Thread im Background aus, denn ansonsten ist deine ganze GUI blockiert bis zum Ende des Suchprozesses.

BTW, welche Exception kommt ?
 
Zuletzt bearbeitet:

Zurück
Oben