Ik heb lokaal wat getest en het lijkt erop dat die exception gegooid wordt wanneer geprobeert wordt te lezen uit een lege input stream nadat de thread, die in de output stream schrijft, afgesloten is.
In mijn tests kreeg ik overigens wel altijd alle gegevens binnen, zelf als ik de leeslus vertraagde met een hoop delays (en de schrijvende de thread dus allang afgesloten is als er nog gegevens worden gelezen); de exception komt steeds pas bij de eerste poging om te lezen uit een lege input stream. Je kunt die exception dus als een soort EOF beschouwen.
Dat klopt ook met de documentatie bij
PipedInputStream.read():
If a thread was providing data bytes to the connected piped output stream, but the thread is no longer alive, then an IOException is thrown.
Als je in de Java code kijkt, zie je ook dat de streams gekoppeld wordt aan een een
readSide en een
writeSide Thread object. Het lijkt er dus op dat het mechanisme een beetje lomp en naar mijn idee niet helemaal in overeenstemming met het principe geïmplementeerd is. Zodra je leest van of schrijft naar een pipe, wordt die blijkbaar gekoppeld aan de thread die dat doet en is de pipe alleen nog maar vanuit die thread te benaderen. Niets aan te doen, ben ik bang.
edit:
Ik kan in mijn tests de fout wel omzeilen door in de tweede thread, vlak voordat die afsluit, de outputstream te closen en vervolgens een tijdje te sleepen, zodat de eerste thread tijd heeft om het EOF karakter te lezen. Dit is ook niet ideaal, want feitelijk weet je niet hoe lang je dan moet sleepen, maar gelukkig kan je
Thread.join() misbruiken om oneindig te sleepen.
Samenvatting; mijn testcode ziet er als volgt uit en dit werkt mooi zonder exceptions:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| import java.io.*;
public class Test
{
private static PipedInputStream pin;
private static PipedOutputStream pout;
static
{
try {
pin = new PipedInputStream();
pout = new PipedOutputStream(pin);
} catch(IOException ioe) {
ioe.printStackTrace();
}
}
public static void main(String[] args) throws IOException
{
BufferedReader reader = new BufferedReader(new InputStreamReader(pin));
Thread thread = new Thread(new ExecuteThread());
thread.start();
String line;
while((line = reader.readLine()) != null)
System.err.println("READ: " + line);
thread.interrupt();
}
private static class ExecuteThread implements Runnable
{
public void run()
{
PrintStream oldOut = System.out;
System.setOut(new PrintStream(pout));
System.out.println("Foo!");
System.out.println("Bar?");
System.out.println("Baz.");
System.out.close();
System.setOut(oldOut);
try {
Thread.currentThread().join();
} catch(InterruptedException ie) {
return;
}
}
}
} |
[
Voor 43% gewijzigd door
Soultaker op 30-01-2004 21:51
]