Reputation: 85
I want to read images inside a .CBZ archive and store them inside an ArrayList. I have tried the following solution but it has, at least, 2 problems.
public class CBZHandler {
final int BUFFER = 2048;
ArrayList<BufferedImage> images = new ArrayList<BufferedImage>();
public void extractCBZ(ZipInputStream tis) throws IOException{
ZipEntry entry;
BufferedOutputStream dest = null;
if(!images.isEmpty())
images.clear();
while((entry = tis.getNextEntry()) != null){
System.out.println("Extracting " + entry.getName());
int count;
FileOutputStream fos = new FileOutputStream("temp");
dest = new BufferedOutputStream(fos,BUFFER);
byte data[] = new byte[BUFFER];
while ((count = tis.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
BufferedImage img = ImageIO.read(new FileInputStream("temp"));
images.add(img);
}
tis.close();
}
}
Upvotes: 1
Views: 267
Reputation: 168825
Each BufferedImage
will typically require significantly more memory than the byte[]
from which it is constructed. Cache the byte[]
and stamp each one out to an image as needed.
Upvotes: 2
Reputation: 1500675
The "OutOfMemoryError" may or may not be inherent in the amount of data you're trying to store in memory. You may need to change your maximum heap size. However, you can certainly avoid writing to disk - just write to a ByteArrayOutputStream
instead, then you can get at the data as a byte array - potentially creating a ByteArrayInputStream
round it if you need to. Do you definitely need to add them in your list as BufferedImage
rather than (say) keeping each as a byte[]
?
Note that if you're able to use Guava it makes the "extract data from an InputStream
" bit very easy:
byte[] data = ByteStreams.toByteArray(tis);
Upvotes: 2