如何在管道的输出端正确完成工作?我需要写入线程来终止或做一些其他的工作,而读取线程读取所有写入的数据。
我应该在写入端关闭管道还是什么?
更新1
我想澄清......根据给出的答案,我是否正确地认为按设计管道行为并不假设任何优雅的终止?
即。一旦打开,停止管道的唯一方法就是打破管道?
当read()
方法返回-1
时,常规流期望流信号结束。我认为管道流不会发生这种情况吗?
答案 0 :(得分:5)
是的,关闭PipedOutputStream会在PipedInputStream上产生-1。
看起来很优雅!这是我的SSCCE:
import java.io.*;
import java.nio.charset.*;
public class SOPipe
{
public static void main(String[] args) throws Exception
{
PipedOutputStream os = new PipedOutputStream();
PipedInputStream is = new PipedInputStream(os);
ReaderThread readerThread = new ReaderThread(is);
WriterThread writerThread = new WriterThread(os);
readerThread.start();
writerThread.start();
readerThread.join();
writerThread.join();
System.out.println("Both Reader and Writer completed.");
System.out.println("Main method returning normally now.");
}
private static final Charset LATIN1 = Charset.forName("latin1");
public static class WriterThread extends Thread
{
private final PipedOutputStream _os;
public WriterThread(PipedOutputStream os)
{
_os = os;
}
public void run()
{
try
{
String msg = "Ceci n'est pas une pipe";
byte[] msgBytes = msg.getBytes(LATIN1);
System.out.println("WriterThread sending message: " + msg);
for(int i = 0; i < msgBytes.length; i++)
{
_os.write(msgBytes, i, 1);
System.out.println("WriterThread wrote a byte!");
_os.flush();
}
_os.close();
System.out.println("[COMPLETED] WriterThread");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
public static class ReaderThread extends Thread
{
private final PipedInputStream _is;
public ReaderThread(PipedInputStream is)
{
_is = is;
}
public void run()
{
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1];
int read;
while ((read = _is.read(buffer, 0, 1)) != -1)
{
System.out.println("ReaderThread read a byte!");
baos.write(buffer, 0, read);
}
System.out.println("[COMPLETED] ReaderThread; received: "
+ new String(baos.toByteArray(), LATIN1));
_is.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
答案 1 :(得分:4)
仅关闭输出流就足够了。
答案 2 :(得分:0)
您可以延长PipedOutputStream
课程&amp;在将所有字节写入管道输出流之后,覆盖其write()
方法以添加自定义逻辑。
public class CustomPipedOutput extends PipedOutputStream {
@Override
public void write(byte[] byteArray, int offset, int length){
super.write(byteArray, offset, length);
//-- Code to be executed after writing bytes
}
@Override
public void close(){
super.close();
//-- Code to be executed after closing piped input stream
}
}
同样,如果需要,可以扩展其他方法。