Reputation: 265
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);
}
}
Upvotes: 1
Views: 563
Reputation: 1500585
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.
Upvotes: 5
Reputation: 38910
From 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:
An attempt was made to read an object when the next element in the stream is primitive data. In this case, the OptionalDataException's length field is set to the number of bytes of primitive data immediately readable from the stream, and the eof field is set to false.
An attempt was made to read past the end of data consumable by a class-defined readObject or readExternal method. In this case, the OptionalDataException's eof field is set to true, and the length field is set to 0.
EDIT: Your code is running fine in my computer too.
From your code,
You are already writing text
as String
object to the file with this statement:
outputOS.writeObject(text);
Below statements may not be needed to write a String by converting it into byte[] and write byte[] length + byte array.
outputOS.writeInt(sigBytes.length);
outputOS.write(sigBytes);
Upvotes: 1