我想象这样的装饰模式:
我知道java io使用这种模式。
我觉得对包装对象存在一些限制,但我无法理解整个规则。
研究代码:
OutputStream outputStream = new FileOutputStream("2.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
ObjectOutputStream objectOutputStreamWrapper = new ObjectOutputStream(objectOutputStream); //double wrapping
objectOutputStreamWrapper.writeObject("this is my string");
objectOutputStreamWrapper.close();
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("2.txt"));
ObjectInputStream objectInputStreamWrapper = new ObjectInputStream(objectInputStream);
System.out.println(objectInputStreamWrapper.readObject());
objectInputStream.close();
OutputStream outputStream = new FileOutputStream("2.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
ObjectOutputStream objectOutputStreamWrapper = new ObjectOutputStream(objectOutputStream); //double wrapping
objectOutputStreamWrapper.writeObject("this is my string");
objectOutputStreamWrapper.close();
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("2.txt"));
//ObjectInputStream objectInputStreamWrapper = new ObjectInputStream(objectInputStream);
System.out.println(objectInputStream.readObject());
objectInputStream.close();
输出:
Exception in thread "main" java.io.OptionalDataException
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1361)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at io.WrappingUnwrappingOrderingTest.main(WrappingUnwrappingOrderingTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
OutputStream outputStream = new FileOutputStream("2.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
// ObjectOutputStream objectOutputStreamWrapper = new ObjectOutputStream(objectOutputStream); //double wrapping
objectOutputStream.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();
输出:
Exception in thread "main" java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2325)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2794)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:801)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at io.WrappingUnwrappingOrderingTest.main(WrappingUnwrappingOrderingTest.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
看起来文件系统中的文件存储有关流装饰顺序的信息。对我来说很奇怪。请澄清这个误解。
我总是应该使用严格相同的装饰器顺序进行输入和输出吗?
答案 0 :(得分:3)
这里的问题是constructing an ObjectOutputStream将一些字节写入基础流:
创建一个写入指定OutputStream的ObjectOutputStream。此构造函数将序列化流标头写入基础流
同样,创建ObjectInputStream会读取序列化头。
因此,如果你打开两个ObjectOutputStream并只使用一个读取,反之亦然,你将不会读取尽可能多的序列化头文件,导致它无法工作,如堆栈跟踪所示:
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:801)
这是ObjectOutputStream非常独特的东西。例如,将缓冲流包装到缓冲流中不会出现此问题。