我知道java I / O使用装饰器模式。但我觉得我理解它错了。
请澄清两个代码段之间的区别:
PipedInputStream pipedInputStream = new PipedInputStream();
PipedOutputStream pipedOutputStream = new PipedOutputStream();
pipedOutputStream.connect(pipedInputStream);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(pipedOutputStream);
objectOutputStream.writeObject("this is my string");
ObjectInputStream objectInputStream = new ObjectInputStream(pipedInputStream);
System.out.println(objectInputStream.readObject());
此应用程序按照我的预期工作,我在控制台中看到结果。
我尝试将ObjectInputStream和ObjectOutputStream包装两次:
PipedInputStream pipedInputStream = new PipedInputStream();
PipedOutputStream pipedOutputStream = new PipedOutputStream();
pipedOutputStream.connect(pipedInputStream);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(pipedOutputStream);
ObjectOutputStream objectOutputStreamWrapper = new ObjectOutputStream(objectOutputStream); //double wrapping
objectOutputStreamWrapper.writeObject("this is my string");
ObjectInputStream objectInputStream = new ObjectInputStream(pipedInputStream);
ObjectInputStream objectInputStreamWrapper = new ObjectInputStream(objectInputStream);
System.out.println(objectInputStreamWrapper.readObject());
此代码暂停。我不明白为什么。请澄清。
P.S。
这只是理论问题。
因为我使用管道而真的挂起了行为(根据EJP回答)。
例如,这段代码符合预期。 OutputStream outputStream = new FileOutputStream("2.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
ObjectOutputStream objectOutputStreamWrapper = new ObjectOutputStream(objectOutputStream); //double wrapping
objectOutputStreamWrapper.writeObject("this is my string");
objectOutputStream.close();
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("2.txt"));
ObjectInputStream objectInputStreamWrapper = new ObjectInputStream(objectInputStream);
System.out.println(objectInputStreamWrapper.readObject());
objectInputStream.close();
看起来如果我用10个装饰器包装输入,我应该以相同的顺序包装10个装饰器的输出。这是真的吗?
我注意到只有刷新的问题:
PipedInputStream pipedInputStream = new PipedInputStream();
PipedOutputStream pipedOutputStream = new PipedOutputStream();
pipedOutputStream.connect(pipedInputStream);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(pipedOutputStream);
ObjectOutputStream objectOutputStreamWrapper = new ObjectOutputStream(objectOutputStream); //double wrapping
objectOutputStreamWrapper.writeObject("this is my string");
objectOutputStreamWrapper.flush();
ObjectInputStream objectInputStream = new ObjectInputStream(pipedInputStream);
ObjectInputStream objectInputStreamWrapper = new ObjectInputStream(objectInputStream);
System.out.println(objectInputStreamWrapper.readObject());
答案 0 :(得分:1)
您滥用管道流。它们旨在由执行写入的生产者线程和执行读取的使用者线程使用。见Javadoc。
管道流共享一个缓冲区,如果读取线程没有读取,它可以填充,这会拖延你的写作线程。
两次包装流并没有任何关系,尽管在这种情况下它肯定是没有意义和有问题的。
答案 1 :(得分:0)
PipedInputStream pipedInputStream = new PipedInputStream();
PipedOutputStream pipedOutputStream = new PipedOutputStream();
pipedOutputStream.connect(pipedInputStream);
//writing
ObjectOutputStream objectOutputStream = new ObjectOutputStream(pipedOutputStream);
//ObjectOutputStream objectOutputStreamWrapper =new ObjectOutputStream(objectOutputStream);
//ObjectOutputStream objectOutputStreamWrapper1=new ObjectOutputStream(objectOutputStreamWrapper);
//objectOutputStreamWrapper1.writeObject("this is my string");
//objectOutputStreamWrapper1.flush();
objectOutputStream.writeObject("this is my string");
//reading
ObjectInputStream objectInputStream = new ObjectInputStream(pipedInputStream);
//ObjectInputStream objectInputStreamWrapper = new ObjectInputStream(objectInputStream);
//ObjectInputStream objectInputStreamWrapper1=new ObjectInputStream(objectInputStreamWrapper);
//System.out.println("going to read from piped source");
//System.out.println(objectInputStreamWrapper1.readObject());
System.out.println(objectInputStream.readObject());
Snippet 1 - 使用Piped流创建的OutputStream,然后输入流直接通过缓冲区从管道接收数据而不刷新。
更新+ 1 - 使用outputstream包装器创建的OutputStream依次使用另一个包装器(注释包装器语句)等等,在flush语句之后工作。 Flush explicitlty将缓冲的数据刷新到底层流,在我们的例子中是管道输出流或输出流。
可以像使用FilterOutputStream一样使用嵌套流,也可以在ObjectOutputStream之上使用。