Serialization 使用ObjectStream从文件读取的BuffereImage为空 描述

Serialization 使用ObjectStream从文件读取的BuffereImage为空 描述,serialization,bufferedimage,javax.imageio,objectinputstream,objectoutputstream,Serialization,Bufferedimage,Javax.imageio,Objectinputstream,Objectoutputstream,在从文件读取主题对象时,主题类有一个临时缓冲图像列表,但使用使用ImageIO读写的自定义读/写对象方法。 问题是,我在一个主题中读取的第一个BuffereImage总是ok(不是null),但其余的都是null,我认为writeObject方法可能有问题,但是什么呢 该程序通过文件夹创建一个主题,其中包含位于该文件夹中的图像。图像没有问题,我用不同的图像检查过,但结果是一样的 数据设置 我认为这是一个众所周知的问题 无法保证ImageReader读取的字节数与ImageWriter最初写入的

在从文件读取主题对象时,主题类有一个临时缓冲图像列表,但使用使用ImageIO读写的自定义读/写对象方法。 问题是,我在一个主题中读取的第一个BuffereImage总是ok(不是null),但其余的都是null,我认为writeObject方法可能有问题,但是什么呢

该程序通过文件夹创建一个主题,其中包含位于该文件夹中的图像。图像没有问题,我用不同的图像检查过,但结果是一样的


数据设置
我认为这是一个众所周知的问题

无法保证
ImageReader
读取的字节数与
ImageWriter
最初写入的字节数相同。它将根据需要读取尽可能多的字节以有效解码(由于缓冲,这可能比写入程序写入的字节多,因为流只是继续)。这可能会导致流“对齐错误”,下一次读取将失败

解决方法是缓冲每次写入,然后在实际图像字节之前写入每个图像的长度(字节计数),或者只写入缓冲的字节数组

在回读时,通过读取或跳过必要的额外字节数,确保您所消耗的字节数与写入的字节数完全相同

要编写,可以使用类似以下代码:

BufferedImage image = null; // your image
ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();
ImageIO.write(image, "JPEG", bufferStream);

byte[] bufferedBytes = bufferStream.toByteArray();

// Write bufferedBytes to ObjectOutputStream as Object, OR write bufferedBytes.length + bufferedBytes as raw bytes
全文如下:

byte[] bytes = ...; // from ObjectInputStream
BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));

我尝试了以下方法:byte[]bytes=((DataBufferByte)bi.getData().getDataBuffer()).getData();然后使用objectstream将长度和字节保存到文件中(文件大小变为85 mb)。然后我像这样读:ImageIO.read(newbytearrayinputstream(bytes)),在读回值之后,但这不起作用。我似乎不明白如何缓冲每次写入,我应该使用ByteArrayStream进行写入和读取吗?在我的数据设置中,我应该仍然使用ObjectOutputStream,因为我的主题类仍然使用默认的读/写对象吗?ImageIO不读取原始字节,因此如果您写入图像的原始字节,您还必须实现自定义读取。我不建议这样做,因为如果你想让它用于任意图像,它需要大量的工作。我用一个代码示例更新了答案,这是一种进行缓冲写入的简单方法。谢谢Harald,你的方法奏效了,现在我开始明白为什么我必须这样做了。非常感谢你的解释。
Checking for Theme Animal
Image is null = false
Image is null = true
Image is null = true
Image is null = true
Image is null = true
Checking for Theme Clown
Image is null = false
Image is null = true
Image is null = true
Image is null = true
Checking for Theme Mountain
Image is null = false
Image is null = true
Checking for Theme Space
Image is null = false
Image is null = true
Image is null = true
BufferedImage image = null; // your image
ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();
ImageIO.write(image, "JPEG", bufferStream);

byte[] bufferedBytes = bufferStream.toByteArray();

// Write bufferedBytes to ObjectOutputStream as Object, OR write bufferedBytes.length + bufferedBytes as raw bytes
byte[] bytes = ...; // from ObjectInputStream
BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));