我在 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:

  1. 当流中的下一个元素是原始数据时,尝试读取对象。在这种情况下,OptionalDataException 的长度字段设置为可立即从流中读取的原始数据的字节数,并且 eof 字段设置为 false。

  2. 试图通过 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 保证填充字节数组,否则如果在完成之前到达流的末尾将抛出异常。