Input/Output Direkt auf Eingabe reagieren

  • Themenstarter Themenstarter triopsfreak
  • Beginndatum Beginndatum
T

triopsfreak

Gast
Ich versuche auf eine Eingabe in ein File direkt zu reagieren, dazu habe ich zwei Threads:
WriteThread
Java:
class WriteThread extends Thread{
	File f = new File("C:/test.txt");
	FileWriter fw = new FileWriter(f);
	
	public WriteThread() throws Exception{
		super();
	}
	@Override
	public void run(){
		Scanner sc = new Scanner(System.in);
		while(sc.hasNextLine()){
			try {
				fw.write(sc.nextLine());
				fw.write(System.getProperty("line.separator"));
				fw.flush();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
Es wird in die Datei geschrieben, das habe ich überprüft, aber der andere Thread reagiert nicht darauf:
ReadThread
Java:
class ReadeThread extends Thread {
	File f = new File("C:/test.txt");

	public ReadeThread() throws Exception {
		super();
	}

	@Override
	public void run() {
		Scanner sc = null;
		try {
			sc = new Scanner(f);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		while (true) {
			if (sc.hasNextLine()) {
				System.out.println(sc.nextLine());
			}
		}

	}

}

Wie muss ich das realisieren? Ich habe es auch schon ohne Endlosschleife probiert, also so:
Java:
	@Override
	public void run() {
		Scanner sc = null;
		try {
			sc = new Scanner(f);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		while(sc.hasNextLine()){
			System.out.println(sc.nextLine());
		}

	}
 
du musst schon jeweils ein komplett neues Scanner-Objekt erstellen,
es wird nur einmal auf der Festplatte nachgeschaut,
so bald das Dateiende (vor dem Schreiben) festgestellt ist ist das Scanner-Objekt eine tote Hülle,
die nur noch Standard-Antworten zurückgibt, ein Zombie 😉

das ist auch eine wichtige Grundeigenschaft von Streams, auf die sich andere Komponenten wie Zippen, Kontrollsummen usw. verlassen,
ein Stream kann nicht einfach wieder anfangen

eine Ausnahme ist System.in oder Netzwerk-Sockets, die sind einfach nie zu Ende, sondern blockieren bis zur nächsten Eingabe,
aber Dateien gehören nicht zu dieser Kategorie

------

in Schleifen solltest du Thread.sleep(100) oder ähnliches einbauen, also 100ms warten,
es reicht 10x pro Sekunde zu prüfen, nicht millionenmal
 
Zuletzt bearbeitet von einem Moderator:
Ok, das wusste ich nicht 😀
Aber oben geht ja eigentlich genau das selbe, ausser dass ich den Scanner da aus System.in aufbaue und dann einfach auf die Eingaben reagieren kann. Gibt es eine Möglichkeit das auch mit einem normalem File zu erreichen?

Edit: Wieso weisst du, was ich noch fragen wollte? 😀
 
> Gibt es eine Möglichkeit das auch mit einem normalem File zu erreichen?

tja, und grundsätzlich ist dafür wohl keine API vorgesehen, du baust es ja mehr weniger selber genau dorthin,
über alle Details möchte ich nicht mutmaßen, z.B. was passiert wenn ein Teil der Datei schon eingelesen ist, dann die Datei aber neu beschrieben wird,
wegen soetwas gibt es ja auch File-Lock usw.
 
Gut, dann habe ich gleich noch eine Frage^^
Du hast gesagt, bei Sockets ist das auch so wie bei System.in, meinst du damit den InputStream, der Socket#getInputStream() zurückgibt?
 
Sockets, System.in + Datei sind alle Streams, beim Lesen InputStreams, ja,
Datei hat eine definierte fertige Quelle, die ohne Verzögerung zum sogar vorher bekannten Ende gelesen werden kann (Länge der Datei bekannt),
die anderen beiden warten gegebenenfalls auf Benutzereingaben, machen Pause

da gibt es natürlich verschiedenste andere Beispiele, etwa ein Stream auf einem byte-Array im Speicher,
ein selbstdefinierer InputStream, der per Zufall neue Zahlen erzeugt oder wartet,
und grundsätzlich möglich ist wiederum auch, übers Netzwerk oder gar System.in eine Datei oder sonstige abgeschlossene Datenmenge zu leiten die auch ein Ende findet
 
Ich habs geschafft, mein Thread sieht nun so aus:
Java:
class ReadeThread extends Thread {
	RandomAccessFile fil = new RandomAccessFile("C:/test.txt", "r");

	public ReadeThread() throws Exception {
		super();
	}

	@Override
	public void run() {
		while (true) {

			try {
				String s = fil.readLine();
				if (null != s) {
					System.out.println(s);
				}
				sleep(100);
			} catch (IOException e) {
				return;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}

}
Ich habs also einfach mit RandomAccessFile gelöst, irgendwie bin ich drauf gekommen, als ich das gelesen habe:
ein selbstdefinierer InputStream, der per Zufall neue Zahlen erzeugt oder wartet,
Zuffal = Random, da hats klick gemacht 😀
 
Doch noch nicht ganz gelöst 🙁
Wie geht das nun, wenn die Dateien auf einem Server sind? RandomAccessFile geht dann nicht mehr, oder gibts da eine Möglichkeit? Und mit dem Socket hab ich einige Probleme, API lesen hat (noch) nichts gebracht, die Insel hilft mir auch nicht weiter... Wie muss das aussehen, damit ich das selbe machen kann wie vorhin, wenn die Datei auf einem anderen Server liegt? Helft mir bitte!
 

Zurück
Oben