在我的下面写作和在ObjectStream中阅读时出了什么问题

时间:2016-01-28 19:13:27

标签: java byte objectinputstream objectoutputstream

下面的代码将我的对象和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)

EDIT 我不能使错误重复在最小值,如下所示???而且我真的为此感到厌倦..

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);
    }
}

2 个答案:

答案 0 :(得分:4)

我相信我明白这里可能出现的问题...您目前正在使用read(sigBytes) 保证它会读取您所有的数据。要求。通常,InputStream.read(byte[])InputStream.read(byte[], int, int)仅保证在返回之前读取某些数据,除非流已关闭。它们完全有可能读取比所要求的更少的数据 - 如果您通过网络读取数据,通常会发生这种情况,例如,流可以返回已经收到的数据,但是赢了& #39; t永远阻止等待更多数据到来。

如果只读取了部分数据,则后续readObject调用将从原始数据中的某个任意点读取,这很容易导致异常被抛出,因为它不太可能是有效对象表示的开始。

在这种情况下,我相信你想要:

inputIS.readFully(sigBytes);

其中readFully 保证填充字节数组,或者如果它在完成之前到达流的末尾则抛出异常。

答案 1 :(得分:1)

来自javadocs

  

异常表示由于未读原始数据导致对象读取操作失败,或者属于流中序列化对象的数据结束。在两种情况下可能会抛出此异常:

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

  2. 尝试通过类定义的readObject或readExternal方法读取可消耗数据的末尾。在这种情况下,OptionalDataException的eof字段设置为true,length字段设置为0.

  3. 编辑:您的代码在我的计算机上运行正常。

    从您的代码中

    您已使用此语句将text作为String对象写入文件:

    outputOS.writeObject(text);
    

    通过将字符串转换为byte []并写入byte [] length + byte array,可能不需要下面的语句来编写字符串。

    outputOS.writeInt(sigBytes.length);
    outputOS.write(sigBytes);