我最近发现了这个成语,我想知道是否有我遗失的东西.我从来没有见过它.我在野外工作的几乎所有Java代码都倾向于将数据压入字符串或缓冲区,而不是像这个例子(例如使用HttpClient和XML API):
final LSOutput output; // XML stuff initialized elsewhere
final LSSerializer serializer;
final Document doc;
// ...
PostMethod post; // HttpClient post request
final PipedOutputStream source = new PipedOutputStream();
PipedInputStream sink = new PipedInputStream(source);
// ...
executor.execute(new Runnable() {
public void run() {
output.setByteStream(source);
serializer.write(doc, output);
try {
source.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}});
post.setRequestEntity(new InputStreamRequestEntity(sink));
int status = httpClient.executeMethod(post);
Run Code Online (Sandbox Code Playgroud)
该代码使用Unix管道样式技术来防止XML数据的多个副本保留在内存中.它使用HTTP Post输出流和DOM Load/Save API将XML Document序列化为HTTP请求的内容.至于我可以告诉它最大限度地减少用很少的额外代码使用的内存(只是几行了Runnable,PipedInputStream和PipedOutputStream).
那么,这个成语有什么问题?如果这个成语没有错,为什么我没有看到它?
编辑:澄清PipedInputStream …
我有两个主题.其中一个写入PipedOutputStream,另一个从相应的PipedInputStream读取.背景是一个线程正在从远程服务器下载一些数据,并通过管道流将其多路复用到其他几个线程.
问题是有时候(特别是在下载大型(> 50Mb)文件时)我得到java.io.IOException:试图从PipedInputStream读取时管道坏了.
Javadoc说,A pipe is said to be broken if a thread that was providing data bytes to the connected piped output stream is no longer alive.
确实,我的写作线程在将所有数据写入PipedOutputStream之后真的死了.
有解决方案吗 如何防止PipedInputStream抛出此异常?我希望能够读取写入PipedOutputStream的所有数据,即使编写线程完成了他的工作.(如果有人知道如何继续写线程直到所有数据都被读取,这个解决方案也是可以接受的).
在以下情况下发生写入结束异常:两个线程:
A: PipedOutputStream put = new PipedOutputStream();
String msg = "MESSAGE";
output.wirte(msg.getBytes());
output.flush();
B: PipedInputStream get = new PipedOutputStream(A.put);
byte[] get_msg = new byte[1024];
get.read(get_msg);
Run Code Online (Sandbox Code Playgroud)
情况如下:A和B同时运行,A写入管道,B读取它.B只是从管道中读取并清除了该管道的缓冲区.然后A不会在未知的时间间隔内将msg写入管道.但是,在某一时刻,B再次读取管道并java.io.IOException: write end dead发生,因为管道的缓冲区仍然是空的.而且我不想睡眠()线程B等待A写管道,这也是不稳定的.如何避免这个问题并解决它?谢谢
Piped流的用例是什么?为什么不将数据读入缓冲区然后将其写出来?