IntelliJ Java IDE
The moose likes I/O and Streams and the fly likes custom object serializations Big Moose Saloon
  Search | Java FAQ | Recent Topics
Register / Login
JavaRanch » Java Forums » Java » I/O and Streams
Reply Bookmark "custom object serializations" Watch "custom object serializations" New topic
Author

custom object serializations

Saiyin Leung
Greenhorn

Joined: Dec 30, 2011
Posts: 3
Hi

I read an article today.

It talks about using ObjectInputStream, ObjectOutputStream and implementing Serializable and Externalizable interfaces...
It also further suggested that one can read/write PDF files... but I have doubt

http://java.sun.com/developer/technicalArticles/Programming/serialization/

here is the text:

public void writeExternal(ObjectOutput out) throws IOException;

public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;

Just override those methods to provide your own protocol. Unlike the previous two serialization variations, nothing is provided for free here, though. That is, the protocol is entirely in your hands. Although it's the more difficult scenario, it's also the most controllable. An example situation for that alternate type of serialization: read and write PDF files with a Java application. If you know how to write and read PDF (the sequence of bytes required), you could provide the PDF-specific protocol in the writeExternal and readExternal methods.


But my understanding is that ObjectInputStream or ObjectOutputStream assumed some specific data in the stream...

For example..

byte b[] = new byte[512];
ByteArrayInputStream is = new ByteArrayInputStream(b);
ObjectInputStream ois = new ObjectInputStream(is);

and I will get java.io.StreamCorruptedException: invalid stream header: 00000000

Obviously I will get the similar error when I try to read a PDF file...


I am wondering if I had read the article wrong..

Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 14610

Saiyin Leung wrote:
For example..

byte b[] = new byte[512];
ByteArrayInputStream is = new ByteArrayInputStream(b);
ObjectInputStream ois = new ObjectInputStream(is);

and I will get java.io.StreamCorruptedException: invalid stream header: 00000000

Obviously I will get the similar error when I try to read a PDF file...


Read this part (the part in bold) again....

Just override those methods to provide your own protocol. Unlike the previous two serialization variations, nothing is provided for free here, though. That is, the protocol is entirely in your hands. Although it's the more difficult scenario, it's also the most controllable. An example situation for that alternate type of serialization: read and write PDF files with a Java application. If you know how to write and read PDF (the sequence of bytes required), you could provide the PDF-specific protocol in the writeExternal and readExternal methods.


It is saying that if you implement the PDF code as readExternal() and writeExternal(), you can use PDF as the format to serialize and deserialize your object. It is *not* saying that PDF is supported. It is saying that with externalizable, you can support it by writing such code.

Or in other words, "ObjectInputStream or ObjectOutputStream assumes some specific data in the stream", but if you implement externalizable, you can change those assumptions.

Henry

Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Saiyin Leung
Greenhorn

Joined: Dec 30, 2011
Posts: 3
Thanks for the reply...

so the author was saying by implementing your own code in readExternal/writeExternal you can read/write PDF files.... thats also what i got from that article...

BUT ObjectInputStream expects the stream starts with some header... how can it be compatible if i implement my own readExternal or writeExternal???

Simply creating the objectinputstream from the fileinputstream on a pdf will get the invalid stream header problem... i don't even have to try readObject...








Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 14610

Saiyin Leung wrote:
BUT ObjectInputStream expects the stream starts with some header... how can it be compatible if i implement my own readExternal or writeExternal???

Simply creating the objectinputstream from the fileinputstream on a pdf will get the invalid stream header problem... i don't even have to try readObject...


The default serialization mechanism expects the header -- and it is the default serialization mechanism that is complaining here. When your object is externalizable, and you implement the writeExternal() and readExternal() methods, you are now 100% responsible for the encoding and decoding.

Your writeExternal() must create the PDF stream, with valid PDF headers. Your readExternal() must read the PDF stream, and complain with an error, if the headers are not PDF headers.


Your readExternal() and writeExternal() methods are 100% not compatible with the default serialization stream.... but when your object is externalizable, object serialization will not use the default encoding and decoding, it will completely switch to use your code. Everything is done by your code, including the headers.


[EDIT: Oh I see what you mean. You are referring to the initial header on the stream. Yeah, you will need to get around that. Probably have you readExternal() and writeExternal() methods to open file streams independent of the object streams. Sorry for the confusion]

Henry

Saiyin Leung
Greenhorn

Joined: Dec 30, 2011
Posts: 3
Hey.. thanks for reply again...

hmm... I still don't get that how would implementing the readExternal/writeExternal will allow me to use that serialization/externalization/object streams
to read a real PDF file... especially I know that the stream header was being searched for before readExternal is called ...

maybe let me try to illustrate with a more trivial example....

import java.io.*;
public class MyPDF implements Serializable, Externalizable {
public static void main(String argv[]) throws Exception {
FileInputStream fis = new FileInputStream("myfile.pdf");
ObjectInputStream ois = new ObjectInputStream(fis);

System.out.println("Reading pdf file");
MyPDF pdf = (MyPDF) ois.readObject();
}
public void writeObject(ObjectOutputStream out) throws IOException {
System.out.println("Inside writeObject");
}
public void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
System.out.println("Inside readObject");
}
public void readExternal(ObjectInput arg0) throws IOException, ClassNotFoundException {
System.out.println("Inside readExternal");
}
public void writeExternal(ObjectOutput arg0) throws IOException {
System.out.println("Inside writeExternal");
}
}


Running this you won't get anything
except "java.io.StreamCorruptedException: invalid stream header: 25504446" right at the " new ObjectInputStream(FileInputStream)" not even getting to my readExternal or readObject...,

I just think the author was simply wrong on the PDF idea... but maybe I am just not getting the idea...
thanks for your time again...
 
 
subject: custom object serializations
 
Threads others viewed
question reg. Serialization process
A question regarding defaultXxxObject()
Wanted to pack values in java like struct.pack() in python
why this works?
question reg. Serialization process
WebSphere development made easy
without the weight of IBM tools
http://www.myeclipseide.com