简体   繁体   中英

Why is readObject hanging when I try to read from an external file?

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();
        }
    }
}

}

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));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM