我有一个我已经序列化的类(“播放器”)(为了保持这个简短,getter一个setter被省略了。)
总而言之,我能够读取和写入对象的所有组件到我的硬盘驱动器上的文件,除了数组中包含的图像。执行下面的“readObject”代码时系统挂起。 (但是,据我所知,也许“writeObject”代码的工作方式与我认为不同。)
我只使用String,int,独立图像尝试了这个代码,它的工作原理!
我在这里研究了一些解决方案,但所有问题都指向在网络上使用这两种方法,而不是保存的文件。
我错过了什么?如果它有帮助,我还提供了下面的包装器组件。
更新:在“readObject”中打印“count”的值会出现一个非常大的数字,这可能解释了为什么它会挂起(参见下面的代码)。但是我不明白的原因是它为什么不读取它保存的相同数字呢?
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));
}
}
}
包装组件:
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();
}
}
}
}
答案 0 :(得分:2)
ois.readInt()
的意外结果清楚地表明您的序列化和反序列化实现不同步。
我想这是因为ImageIO.read()
实际读取的字节多于解码图像所需的字节数。
尝试使用实际长度预先添加图像数据:
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ImageIO.write(image, "png", buffer);
oos.writeInt(buffer.size());
oos.write(buffer.toByteArray());
并使用它仅向ImageIO.read()
提供有限的流块:
int imageLength = ois.readInt();
byte[] buffer = new byte[imageLength];
ois.read(buffer);
this.image = ImageIO.read(new ByteArrayInputStream(buffer));