ZipFile Fun Java 8 style

I’ve been playing around with cbz and cbr files (comics). the cbz files are actually zip files and can be processed as such.

I was interested in all jpg files in the archive to retrieve all the pages of the comic. Here is how I did it:

Get all filenames I want from an archive

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Override
public List<String> pages(final File file) {
try {
final ZipFile zip = new ZipFile(file);
return zip.stream()
.filter(p -> !p.isDirectory())
.filter(p -> !p.getName()
.startsWith("."))
.filter(p -> !p.getName()
.startsWith("__MACOSX"))
.filter(p -> p.getName()
.toLowerCase()
.endsWith("jpg") || p.getName()
.toLowerCase()
.endsWith(".jpeg"))
.map(ZipEntry::getName)
.collect(Collectors.toList());
} catch (final IOException e) {
throw new RuntimeException(e);
}
}

Lets break it down:

  • first ask for the stream() api (java 8)
  • throw away all directory entries
  • ignore all files staring with a “.” or “__MACOSX”
  • keep all jp(e)g files
  • now map all the left over entries to the getName of the ZipEntry
  • collect them to a list

and now I’ve got my list of pages but what if I want to retrieve a single file from the archive?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Override
public byte[] page(final File file, final String page) {

try {
final ZipFile zip = new ZipFile(file);
final ZipEntry zipEntry = zip.stream()
.filter(p -> p.getName()
.equals(page))
.findAny()
.orElse(null);
if (zipEntry != null) {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final InputStream inputStream = zip.getInputStream(zipEntry);
final byte[] buffer = new byte[BUFFER];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
outputStream.close();
return outputStream.toByteArray();
}

} catch (final IOException e) {
throw new RuntimeException(e);
}

return null;
}

I’m thinking that the last part can also be done through the original lambda but I haven’t figured it out yet.