Java 多个引号会导致PipedOutStream/OutputStreamWriter失败
当我试图将Java 多个引号会导致PipedOutStream/OutputStreamWriter失败,java,stream,Java,Stream,当我试图将OutputStream复制到InputStream时,我无意中发现了pipedoutpstream的一个非常奇怪的行为。另见 下面是一个小单元测试方法: @Test public void pipeTest() { PipedInputStream pin = null; try { pin = new PipedInputStream(); PipedOutputStream pout = new PipedOutputStream(
OutputStream
复制到InputStream
时,我无意中发现了pipedoutpstream
的一个非常奇怪的行为。另见
下面是一个小单元测试方法:
@Test
public void pipeTest() {
PipedInputStream pin = null;
try {
pin = new PipedInputStream();
PipedOutputStream pout = new PipedOutputStream(pin);
OutputStreamWriter writer = new OutputStreamWriter(pout);
for (int i = 0; i < 100; i++) {
writer.write("\"Test\";" + i + "\n");
// writer.write("\"Test\";" + "\"" + i + "\"\n");
}
writer.close();
pout.close();
System.out.print(IOUtils.toString(pin));
} catch (IOException e) {
System.out.print(e);
} finally {
IOUtils.closeQuietly(pin);
}
}
@测试
公共管道测试(){
PipedInputStream引脚=空;
试一试{
pin=新的PipedInputStream();
PipedOutputStream pout=新的PipedOutputStream(pin);
OutputStreamWriter writer=新的OutputStreamWriter(pout);
对于(int i=0;i<100;i++){
writer.write(“\”Test\”;“+i+”\n”);
//write.write(“\”Test\”;“+”\“+i+”\”\n”);
}
writer.close();
闭上嘴;
系统输出打印(IOUtils.toString(pin));
}捕获(IOE异常){
系统输出打印(e);
}最后{
IOUtils.安静关闭(pin);
}
}
这很好,可以打印出100行。如果取消对第二条write语句的注释并注释掉第一条语句,writer.close()
会被卡住,永远不会结束。第二组引号似乎有问题。
有人知道为什么会出现这种情况以及如何避免这种情况吗?这与引号无关,而与您正在编写的数据量有关。为了演示这一点,您可以完全摆脱编写器和循环,只需使用:
pout.write(new byte[1024]);
或者保留现有代码,但请确保它可以正常工作(因为它可以写入1000字节):
但这没有(因为它尝试写入1100字节):
这是可行的——但如果将其更改为1025,它将永远挂起……因为默认情况下,内部缓冲区的长度为1024字节,并且没有任何东西在消耗流。(在完成编写之前,您不会从pin
读取。)由于前1024个字节中没有任何一个被占用,所以没有地方放置第1025个字节,因此write
会一直阻塞,直到有空间为止
你可以:
- 在构建
时更改管道大小,使其具有更大的缓冲区PipedInputStream
- 在书写时从管道中读取-例如,在单独的线程中
pout.write(new byte[1024]);
或者保留现有代码,但请确保它可以正常工作(因为它可以写入1000字节):
但这没有(因为它尝试写入1100字节):
这是可行的——但如果将其更改为1025,它将永远挂起……因为默认情况下,内部缓冲区的长度为1024字节,并且没有任何东西在消耗流。(在完成编写之前,您不会从pin
读取。)由于前1024个字节中没有任何一个被占用,所以没有地方放置第1025个字节,因此write
会一直阻塞,直到有空间为止
你可以:
- 在构建
时更改管道大小,使其具有更大的缓冲区PipedInputStream
- 在书写时从管道中读取-例如,在单独的线程中
pout.write(new byte[1024]);
或者保留现有代码,但请确保它可以正常工作(因为它可以写入1000字节):
但这没有(因为它尝试写入1100字节):
这是可行的——但如果将其更改为1025,它将永远挂起……因为默认情况下,内部缓冲区的长度为1024字节,并且没有任何东西在消耗流。(在完成编写之前,您不会从pin
读取。)由于前1024个字节中没有任何一个被占用,所以没有地方放置第1025个字节,因此write
会一直阻塞,直到有空间为止
你可以:
- 在构建
时更改管道大小,使其具有更大的缓冲区PipedInputStream
- 在书写时从管道中读取-例如,在单独的线程中
pout.write(new byte[1024]);
或者保留现有代码,但请确保它可以正常工作(因为它可以写入1000字节):
但这没有(因为它尝试写入1100字节):
这是可行的——但如果将其更改为1025,它将永远挂起……因为默认情况下,内部缓冲区的长度为1024字节,并且没有任何东西在消耗流。(在完成编写之前,您不会从pin
读取。)由于前1024个字节中没有任何一个被占用,所以没有地方放置第1025个字节,因此write
会一直阻塞,直到有空间为止
你可以:
- 在构建
时更改管道大小,使其具有更大的缓冲区PipedInputStream
- 在书写时从管道中读取-例如,在单独的线程中
A
PipedInputStream
有一个内部缓冲区。默认情况下,缓冲区为1024字节,但您可以将不同的大小传递给PipedInputStream
的构造函数
当缓冲区已满时,写入与PipedInputStream
关联的PipedOutputStream
块,直到从后者读取足够的数据,以便缓冲区中有足够的空间
您的问题与双引号本身无关;只是在添加双引号时写入了更多数据
您应该只在多线程代码中使用管道流(其中一个线程写入管道输出流,另一个线程读取管道输入流),以避免这种可能的死锁
PipedInputStream
的Javadoc有一个明确的警告:
尝试从一个线程使用两个对象是不正确的
建议使用,因为它可能会使线程死锁
A公司