what's going wrong in my below writing and reading in ObjectStream

below code to write my objects and byte[] into file with sigBytes being my byte[]

ObjectOutputStream outputOS = new ObjectOutputStream(new FileOutputStream(outputFile));
    outputOS.writeInt(sigBytes.length);
    outputOS.write(sigBytes);
    outputOS.writeObject(text);
    outputOS.close();

then when i execute code below i get an 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();

Below the error I get at 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 i can't make the error repeat in a minimal as below??? and i'm really to tired for this..

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);
    }
}
Jon Skeet
people
quotationmark

I believe I understand what may be going wrong here... you're currently using read(sigBytes) which does not guarantee that it will read all the data you've requested. In general, InputStream.read(byte[]) and InputStream.read(byte[], int, int) only guarantee that they will read some data before returning, unless the stream is closed. It's entirely possible for them to read less data than is asked for - this often happens if you're reading data over a network, for example, where the stream can return the data it has already received, but won't block forever waiting for more data to come.

If only part of your data is read, then the subsequent readObject call will be reading from some arbitrary point within your original data, which could easily cause an exception to be thrown as it's unlikely to be the start of a valid object representation.

In this case, I believe you want:

inputIS.readFully(sigBytes);

where readFully is guaranteed to fill the byte array, or will throw an exception if it reaches the end of the stream before completing.

people

See more on this question at Stackoverflow