Java 从.cbz存档读取图像

Java 从.cbz存档读取图像,java,image,out-of-memory,bufferedimage,Java,Image,Out Of Memory,Bufferedimage,我想读取.CBZ存档中的图像并将其存储在ArrayList中。我尝试过以下解决方案,但至少有两个问题 将10-15个图像添加到ArrayList后,我出现OutOfMemory错误 必须有一种更好的方法来获取ArrayList中的图像,而不是将它们写入临时文件并再次读取 公共类CBZHandler{ 最终整数缓冲区=2048; ArrayList images=新的ArrayList(); public void extractCBZ(zipinputtis)引发IOException{ Zi

我想读取.CBZ存档中的图像并将其存储在ArrayList中。我尝试过以下解决方案,但至少有两个问题

  • 将10-15个图像添加到ArrayList后,我出现OutOfMemory错误
  • 必须有一种更好的方法来获取ArrayList中的图像,而不是将它们写入临时文件并再次读取

  • 公共类CBZHandler{
    最终整数缓冲区=2048;
    ArrayList images=新的ArrayList();
    public void extractCBZ(zipinputtis)引发IOException{
    ZipEntry入口;
    BufferedOutputStream dest=null;
    如果(!images.isEmpty())
    图像。清除();
    while((entry=tis.getNextEntry())!=null){
    System.out.println(“提取”+entry.getName());
    整数计数;
    FileOutputStream fos=新的FileOutputStream(“临时”);
    dest=新的缓冲输出流(fos,缓冲区);
    字节数据[]=新字节[缓冲区];
    而((计数=tis.read(数据,0,缓冲区))!=-1){
    目的写入(数据,0,计数);
    }
    dest.flush();
    dest.close();
    buffereImage img=ImageIO.read(新文件输入流(“temp”);
    图像。添加(img);
    }
    tis.close();
    }
    }
    
    在试图存储在内存中的数据量中,“OutOfMemoryError”可能是固有的,也可能不是固有的。您可能需要更改最大堆大小。但是,您当然可以避免写入磁盘—只需将数据写入
    ByteArrayInputStream
    ,然后就可以将数据作为字节数组获取—如果需要,可能会创建一个
    ByteArrayInputStream
    。您是否确实需要将它们作为
    BufferedImage
    添加到列表中,而不是(比如)将它们保留为
    字节[]

    请注意,如果您能够使用它,则“从
    InputStream
    提取数据”位非常容易:

    byte[] data = ByteStreams.toByteArray(tis);
    

    每个
    buffereImage
    通常需要比构建它的
    字节[]
    多得多的内存。缓存
    字节[]
    并根据需要将每个字节戳出一个图像。

    ImageIO从输入流读取。为什么不将ZipInputStream(
    tis
    )传递给
    ImageIO.read()
    ?图像的大小(以字节为单位)和JVM堆的大小?了解这些图像的分辨率(宽度*高度,可能*颜色深度)也有助于估计内存使用情况。我运行OOM看起来很奇怪,因为到目前为止,我的代码都在运行这个例程。感谢ByteArrayOutputStream的提示。将它们存储为字节有什么好处?@AlfioCastorina:我们可以想象,这些图像具有较高的压缩级别,
    buffereImage
    很可能会将其转换为每个像素的内存位图表示,这将比文件中的数据大得多。
    byte[] data = ByteStreams.toByteArray(tis);