Ich habe versucht, eine InputStream zu implementieren, die ich Blöcke von Zeichenfolgen daran übergeben kann.
Technisch sollte es funktionieren, weil alles, was ich tun musste, die InputStream # read() -Methode zu blockieren, und das ist es. Oder so dachte ich so ... Hier ist meine individuelle Umsetzung des StringInputStream ist:Benutzerdefinierte Implementierung von InputStream mit LinkedBlockingQueue hängen
public class StringInputStream extends InputStream {
private LinkedBlockingQueue<Integer> buffer = new LinkedBlockingQueue<>();
public void supplyData(String s) {
for (char ch : s.toCharArray()) {
buffer.add((int) ch);
}
}
@Override
public int read() throws IOException {
try {
return buffer.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
return -1;
}
}
Und hier ist mein Code, um es zu testen:
public class StreamsMain {
public static void main(String[] args) throws InterruptedException {
InputStream is = new ByteArrayInputStream("eu ma duc la scoala\n sa ma distrez\nsi imi place la MAXIM!".getBytes(StandardCharsets.UTF_8));
Scanner scanner1 = new Scanner(is);
AtomicReference<StringInputStream> inputStream = new AtomicReference<>(new StringInputStream());
Thread th = new Thread(() -> {
Scanner scanner = new Scanner(inputStream.get());
while (scanner.hasNextLine()) {
System.out.println("2. " + scanner.nextLine());
}
});
th.start();
while (scanner1.hasNextLine()) {
String line = scanner1.nextLine();
inputStream.get().supplyData(line + "\n");
System.out.println("1. " + line);
}
System.out.println("\n\nwaiting 3 seconds to exit from MAIN thread");
TimeUnit.SECONDS.sleep(3);
//th.interrupt();
System.out.println("exited MAIN thread");
}
}
In meinem Beispiel lese ich aus der erster Eingabestream, gebe ich die Zeilen zu meiner benutzerdefinierten Implementierung und dann lese ich von meiner benutzerdefinierten Implementierung in einem anderen Thread. Die seltsame Sache: Ich sehe keine Ausgabe, OHNE dass ich die th.interrupt() Zeile zerlege und das passiert NUR das Schlafen vom Hauptthread (was keinen Sinn ergibt, weil ich von meinem StringInputStream in einem anderen Thread).
Können Sie mir bitte helfen, das Problem zu erkennen?
Mit freundlichen Grüßen
FYI: Ein 'InputStream' dient zum Lesen von _bytes_. Ein 'Reader' dient zum Lesen von _characters_ oder Strings. Sie sollten wirklich nicht die beiden verwechseln. –
Ich wette, der 'Scanner' verwendet gepufferte I/O und der gesamte Inhalt, den Sie drücken, ist kleiner als diese Puffergröße. Es wartet also auf mehr eingehende Daten, wenn Sie nichts mehr tun. Da Sie '-1', aka Dateiende, bei Unterbrechung zurückgeben, wird das Warten beendet. Die richtige Lösung wäre es, eine Art End-of-File-Markierung in den Stream zu schieben, den der konsumierende Thread lesen kann. – Holger