ObjectInputStream over DeflaterInputStream throws StreamCorruptedException [duplicate] - java

This question already has answers here:
DeflatorInputStream and DeflatorOutputStream do not reconstruct the original data
(3 answers)
Closed 5 years ago.
I'm trying to use ObjectOutputStream over a DeflaterOutputStream to write deflated data into an underlying stream. But when I try to read the data with their InputStream counterparts, an exception is thrown. It is worth of note that replacing Deflate{Output,Input}Stream with GZip{Output,Input}Stream, it works as expected. An example code that shows this behavior can be seen below:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try(ObjectOutputStream oos = new ObjectOutputStream(new DeflaterOutputStream(baos))) {
oos.writeObject("test");
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
try(ObjectInputStream oos = new ObjectInputStream(new DeflaterInputStream(bais))) {
System.out.println(oos.readObject());
}
It throws the following exception:
Exception in thread "main" java.io.StreamCorruptedException: invalid stream header: 789CAB98
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:857)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:349)
at Main.main(Main.java:23)
Does anyone know why exacly this happens?

I've already figured it out and it is a silly mistake. But answering my own question so future people don't fall for it again:
The inverse class of DeflaterOutputStream is InflaterInputStream, not DeflaterInputStream. So the code should look like the one below:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try(ObjectOutputStream oos = new ObjectOutputStream(new DeflaterOutputStream(baos))) {
oos.writeObject("test");
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
try(ObjectInputStream oos = new ObjectInputStream(new InflaterInputStream(bais))) {
System.out.println(oos.readObject());
}

Related

Getting Object back from an ObjectOutputStream

I have created an ObjectOutputStream
ObjectOutputStream stream = new ObjectOutputStream(new ByteArrayOutputStream());
stream.writeObject(myObject);
but how do I now convert this back into an Object, or even a ByteArray?
I've tried getting an ObjectInputStream like this
ByteArrayOutputStream outputStream = (ByteArrayOutputStream) myProcess.getOutputStream();
final ObjectInputStream objectInputStream = new ObjectInputStream(
new ByteArrayInputStream(outputStream.toByteArray()));
however I get a compile error saying it can't cast the ObjectOutputStream to a ByteArrayOutputStream; yet there seem to be no methods on the ObjectOutputStream to get the data back?
Here how you do it
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream stream = new ObjectOutputStream(baos);
stream.writeObject(myObject);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream inputStream = new ObjectInputStream(bais);
Object o = inputStream.readObject();

Is there any way to convert PrintWriter into ByteArrayOutputStream?

I want to convert PrintWriter object into ByteArrayOutputStream. and this I am displaying as a PDF.
I don't know how you are using PrintWriter exactly (please post your code), but instead of converting objects you can write lines directly to ByteArrayOutputStream like this:
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(byteStream);
pw.write("example");
pw.flush();
or (flush after closing PrintWriter):
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(byteStream);
pw.write("example");
pw.close();
or (auto-flushable):
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(byteStream, true);
pw.println("example");
Let me know whether you prefer other solution and add some more details then(your code).

what about one BufferedOutputStream wrap another BufferedOutputStream?

what about one BufferedOutputStream wrap another BufferedOutputStream? this question is simple. but confused.
As the following code,
OutputStream file = new FileOutputStream("test.txt");
OutputStream buffer = new BufferedOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(buffer); //wrap buffer twice
OutputStream outputStream = new ObjectOutputStream(bufferedOutputStream); // wrap as ObjectOutputStream
BufferedOutputStream bufferedOutputStream1 = new BufferedOutputStream(outputStream); //wrap back as BufferedOutputStream
ObjectOutput output = new ObjectOutputStream(bufferedOutputStream1);
What about it? Question?
If you're asking whether an inefficiency is introduced, the answer is 'no'. The code is optimised to handle that case, or rather the case where the transfer size >= the buffer size.

Pass serilaized object as parameter to HTTPServer in Java

How can I pass a serilaized object as a param in a GET request to my HTTPServer? Please let me know as I have been unable to find a way to do the same.
You can try something like this
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.close();
String prm = URLEncoder.encode(new String(bos.toByteArray(), "ISO-8859-1"), "ISO-8859-1");
On the server side:
servletRequest.setCharacterEncoding("ISO-8859-1");
String s = servletRequeset.getParameter("obj");
byte[] bytes = s.getBytes("ISO-8859-1");
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
Object obj = ois.readObject();
It's also possible to use Base64 instead of URL Encoding, the main idea is to pass serialized bytes in URL

byte array in java returning null after conversion from objects

I need to send my phone contacts in android as bytes. So i have crated a bean class implementing serializable , but after converting the arraylist of bean class to byte array, byte array is always showing null. Here is my sample code.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(presentContacts);
byte[] buf = baos.toByteArray();
Here presentContacts is the ArrayList of bean class. Byte array, buf is always returning null but presentContacts is not null.
You should probably close or at least flush the ObjectOutputStream.
Something like this
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(presentContacts);
oos.flush();
byte[] buf = baos.toByteArray();

Categories