Reputation: 55
I have a class ("Player") that I have serialized (getters an setters omitted to keep this brief).
To make a long story short, I am able to read and write all components of the object to a file on my hard drive, EXCEPT for images contained in the array. The system HANGS when executing the "readObject" code below. (BUT, for all I know, maybe the "writeObject" code isn't working the way I think it is).
I have tried this code with just the String, the int, the stand-alone image, and it works!
I have researched some solutions here, but all questions point to using these two methods over a network, not a saved file.
What am I missing? I have also provided the wrapper components below if it helps.
UPDATE: Printing the value of "count" in "readObject" comes up with a ridiculously large number, which might explain why it is hanging (see code below). BUT what I don't understand is why isn't it reading the same number that it saved?
public class Player implements Serializable {
private static final long serialVersionUID = -8193759868470009555L;
private String someString = "";
private int someInt = 0;
private transient BufferedImage image = null;
private transient ArrayList<BufferedImage> imageArray = new ArrayList<BufferedImage>();
private void writeObject(ObjectOutputStream oos){
oos.defaultWriteObject();
// Image
ImageIO.write(image, "png", oos);
// Number of images in array
oos.writeInt(imageArray.size());
for (BufferedImage image: imageArray){
ImageIO.write(image, "png", oos);
}
}
private void readObject(ObjectInputStream ois){
ois.defaultReadObject();
// Image
this.image = ImageIO.read(ois);
// Number of images in array
imageArray = new ArrayList<BufferedImage>();
int count = ois.readInt();
//****** count = 415301485
for (int i=0; i<count; i++){
imageArray.add(ImageIO.read(ois));
}
}
}
Wrapper components:
public static Object LoadObject(String filename){
FileInputStream fis = null;
ObjectInputStream ois = null;
Object obj = null;
try {
fis = new FileInputStream(filename);
ois = new ObjectInputStream(fis);
obj = ois.readObject();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (ois!=null){
try {
ois.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (fis!=null){
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return obj;
}
public static void SaveObject(Object obj, String filename){
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream(filename);
oos = new ObjectOutputStream(fos);
oos.writeObject(obj);
oos.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (oos!=null){
try {
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (fos!=null){
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Upvotes: 0
Views: 244
Reputation: 242686
Unexpected result of ois.readInt()
clearly indicates that your serialization and deserialization implementations are out of sync.
I guess it happens because ImageIO.read()
actually reads more bytes than it need to decode an image.
Try to prepend image data with its actual length:
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ImageIO.write(image, "png", buffer);
oos.writeInt(buffer.size());
oos.write(buffer.toByteArray());
and use it to supply only limited chunk of the stream to ImageIO.read()
:
int imageLength = ois.readInt();
byte[] buffer = new byte[imageLength];
ois.read(buffer);
this.image = ImageIO.read(new ByteArrayInputStream(buffer));
Upvotes: 2