我在 ObjectStream 中的以下写作和阅读出了什么问题
what's going wrong in my below writing and reading in ObjectStream
下面的代码将我的对象和 byte[] 写入文件,其中 sigBytes 是我的 byte[]
ObjectOutputStream outputOS = new ObjectOutputStream(new FileOutputStream(outputFile));
outputOS.writeInt(sigBytes.length);
outputOS.write(sigBytes);
outputOS.writeObject(text);
outputOS.close();
然后当我执行下面的代码时,我得到一个 java.io.OptionalDataException
ObjectInputStream inputIS = new ObjectInputStream(new FileInputStream(INPUT));
int length = inputIS.readInt();
byte[] sigBytes = new byte[length];
inputIS.read(sigBytes, 0, length);
String text = (String) inputIS.readObject();
低于我在 String text = (String) inputIS.readObject()
得到的错误:
java.io.OptionalDataException
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at encryption3.Encryption3.decrypt(Encryption3.java:34)
at encryption3.Encryption3.main(Encryption3.java:53)
编辑
我不能让错误重复如下???我真的很累..
public static void doThings() {
try {
File file = new File("C:/edges/input.ext");
String text = "Hello";
file.createNewFile();
byte[] sigBytes = (text).getBytes();
ObjectOutputStream outputOS = new ObjectOutputStream(new FileOutputStream(file));
outputOS.writeInt(sigBytes.length);
outputOS.write(sigBytes);
outputOS.writeObject(text);
ObjectInputStream inputIS = new ObjectInputStream(new FileInputStream(file));
int length = inputIS.readInt();
byte[] sigBytes2 = new byte[length];
inputIS.read(sigBytes2, 0, length);
String text2 = (String) inputIS.readObject();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(EncryptionError.class.getName()).log(Level.SEVERE, null, ex);
}
}
来自javadocs
Exception indicating the failure of an object read operation due to unread primitive data, or the end of data belonging to a serialized object in the stream. This exception may be thrown in two cases:
当流中的下一个元素是原始数据时,尝试读取对象。在这种情况下,OptionalDataException 的长度字段设置为可立即从流中读取的原始数据的字节数,并且 eof 字段设置为 false。
试图通过 class 定义的 readObject 或 readExternal 方法读取超过数据消耗的末尾。在这种情况下,OptionalDataException 的 eof 字段设置为 true,长度字段设置为 0。
编辑:您的代码 运行 在我的电脑上也很好。
根据您的代码,
您已经使用以下语句将 text
作为 String
对象写入文件:
outputOS.writeObject(text);
将字符串转换为byte[]并写入byte[]长度+字节数组,可能不需要以下语句。
outputOS.writeInt(sigBytes.length);
outputOS.write(sigBytes);
我相信我明白这里可能出了什么问题...您目前使用的 read(sigBytes)
不 保证它会读取您的所有数据'要求。一般来说,InputStream.read(byte[])
和 InputStream.read(byte[], int, int)
只保证它们会在 returning 之前读取 一些 数据,除非流已关闭。他们读取的数据完全有可能比要求的少 - 如果您通过网络读取数据,这种情况经常发生,例如,流可以 return 它已经收到的数据,但不会永远阻塞等待更多数据的到来。
如果只读取了部分数据,那么随后的 readObject
调用将从原始数据中的任意点读取,这很容易导致抛出异常,因为它不太可能是有效对象表示的开始。
在这种情况下,我相信你想要:
inputIS.readFully(sigBytes);
其中readFully
是保证填充字节数组,否则如果在完成之前到达流的末尾将抛出异常。
下面的代码将我的对象和 byte[] 写入文件,其中 sigBytes 是我的 byte[]
ObjectOutputStream outputOS = new ObjectOutputStream(new FileOutputStream(outputFile));
outputOS.writeInt(sigBytes.length);
outputOS.write(sigBytes);
outputOS.writeObject(text);
outputOS.close();
然后当我执行下面的代码时,我得到一个 java.io.OptionalDataException
ObjectInputStream inputIS = new ObjectInputStream(new FileInputStream(INPUT));
int length = inputIS.readInt();
byte[] sigBytes = new byte[length];
inputIS.read(sigBytes, 0, length);
String text = (String) inputIS.readObject();
低于我在 String text = (String) inputIS.readObject()
得到的错误:
java.io.OptionalDataException at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371) at encryption3.Encryption3.decrypt(Encryption3.java:34) at encryption3.Encryption3.main(Encryption3.java:53)
编辑 我不能让错误重复如下???我真的很累..
public static void doThings() {
try {
File file = new File("C:/edges/input.ext");
String text = "Hello";
file.createNewFile();
byte[] sigBytes = (text).getBytes();
ObjectOutputStream outputOS = new ObjectOutputStream(new FileOutputStream(file));
outputOS.writeInt(sigBytes.length);
outputOS.write(sigBytes);
outputOS.writeObject(text);
ObjectInputStream inputIS = new ObjectInputStream(new FileInputStream(file));
int length = inputIS.readInt();
byte[] sigBytes2 = new byte[length];
inputIS.read(sigBytes2, 0, length);
String text2 = (String) inputIS.readObject();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(EncryptionError.class.getName()).log(Level.SEVERE, null, ex);
}
}
来自javadocs
Exception indicating the failure of an object read operation due to unread primitive data, or the end of data belonging to a serialized object in the stream. This exception may be thrown in two cases:
当流中的下一个元素是原始数据时,尝试读取对象。在这种情况下,OptionalDataException 的长度字段设置为可立即从流中读取的原始数据的字节数,并且 eof 字段设置为 false。
试图通过 class 定义的 readObject 或 readExternal 方法读取超过数据消耗的末尾。在这种情况下,OptionalDataException 的 eof 字段设置为 true,长度字段设置为 0。
编辑:您的代码 运行 在我的电脑上也很好。
根据您的代码,
您已经使用以下语句将 text
作为 String
对象写入文件:
outputOS.writeObject(text);
将字符串转换为byte[]并写入byte[]长度+字节数组,可能不需要以下语句。
outputOS.writeInt(sigBytes.length);
outputOS.write(sigBytes);
我相信我明白这里可能出了什么问题...您目前使用的 read(sigBytes)
不 保证它会读取您的所有数据'要求。一般来说,InputStream.read(byte[])
和 InputStream.read(byte[], int, int)
只保证它们会在 returning 之前读取 一些 数据,除非流已关闭。他们读取的数据完全有可能比要求的少 - 如果您通过网络读取数据,这种情况经常发生,例如,流可以 return 它已经收到的数据,但不会永远阻塞等待更多数据的到来。
如果只读取了部分数据,那么随后的 readObject
调用将从原始数据中的任意点读取,这很容易导致抛出异常,因为它不太可能是有效对象表示的开始。
在这种情况下,我相信你想要:
inputIS.readFully(sigBytes);
其中readFully
是保证填充字节数组,否则如果在完成之前到达流的末尾将抛出异常。