Java NIO Zip File System Equivalent to setMethod () in java.util.zip.ZipEntry

I have some existing code for creating zip files in Epub 2 format that works correctly.

When trying to update my code to support the Epub 3 format, I thought that I would try to use the Java NIO Zip file system instead of java.util.zip.ZipFile . I'm almost there, except for one tiny thing.

There is a 20-byte mimetype file required in the Epub format, which must be placed in a ZIP file in uncompressed form. java.util.zip.ZipEntry api provides setMethod(ZipEntry.STORED) to achieve this.

I cannot find references to this in the Java NIO FileSystem API document. Is there an equivalent to ZipEntry.setMethod() ?

EDIT 1

OK, so I see how to display attributes, and thanks for this example, but I cannot find any document on how to create an attribute such as (zip: method, 0), even on Oracle oracle. Java NIO enhancements to Java seem only about 20% documented to me. The api doc attributes are very scarce, especially how to create attributes.

The feeling I'm starting to get is that the NIO Zip file system may not be improved on java.util.zip and requires more code to achieve the same result.

EDIT 2

I tried the following:

 String contents = "application/epub+zip"; /* contents of mimetype file */ Map<String, String> map = new HashMap<>(); map.put("create", "true"); Path zipPath = Paths.get("zipfstest.zip"); Files.deleteIfExists(zipPath); URI fileUri = zipPath.toUri(); // here URI zipUri = new URI("jar:" + fileUri.getScheme(), fileUri.getPath(), null); try (FileSystem zipfs = FileSystems.newFileSystem(zipUri, map)) { Path pathInZip = zipfs.getPath("mimetype"); Files.createFile(pathInZip, new ZipFileAttribute<Integer>("zip:method", 0)); byte[] bytes = contents.getBytes(); Files.write(pathInZip, bytes, StandardOpenOption.WRITE); } 

The ZipFileAttribute class is a minimal implementation of the attribute interface. I can publish it, but it's just a key-value pair (name, value)

This code successfully created the zipFile, but when I open the zipFile with 7zip, I see that the mimetype file was stored in the zip as DEFLATED (8), and not the one I need, which is stored (0). So the question is how to properly encode an attribute so that it is stored as STORED.

+7
java compression zip nio
source share
2 answers

This is not well documented, but the JDK file system zip provider supports a FileAttributeView named zip .

Here is the code from my inbox:

 public static void main(final String... args) throws IOException { final Path zip = Paths.get("/home/fge/t.zip"); final Map<String, ?> env = Collections.singletonMap("readonly", "true"); final URI uri = URI.create("jar:" + zip.toUri()); try ( final FileSystem fs = FileSystems.newFileSystem(uri, env); ) { final Path slash = fs.getPath("/"); Files.readAttributes(slash, "zip:*").forEach( (key, val) -> { System.out.println("Attribute name: " + key); System.out.printf("Value: %s (class: %s)\n", val, val != null ? val.getClass(): "N/A"); }); } } 

Output:

 Attribute name: size Value: 0 (class: class java.lang.Long) Attribute name: creationTime Value: null (class: N/A) Attribute name: lastAccessTime Value: null (class: N/A) Attribute name: lastModifiedTime Value: 1969-12-31T23:59:59.999Z (class: class java.nio.file.attribute.FileTime) Attribute name: isDirectory Value: true (class: class java.lang.Boolean) Attribute name: isRegularFile Value: false (class: class java.lang.Boolean) Attribute name: isSymbolicLink Value: false (class: class java.lang.Boolean) Attribute name: isOther Value: false (class: class java.lang.Boolean) Attribute name: fileKey Value: null (class: N/A) Attribute name: compressedSize Value: 0 (class: class java.lang.Long) Attribute name: crc Value: 0 (class: class java.lang.Long) Attribute name: method Value: 0 (class: class java.lang.Integer) 

It looks like the zip: method attribute.

So, if you want to change the method, if you have Path in your zip file system, it looks like you can do (UNTESTED!):

 Files.setAttribute(thePath, "zip:method", ZipEntry.DEFLATED); 
+2
source share

Based on a very interesting answer below, I re-read all the available API documents and tried various guesses when setting the attribute. I drew a space on both. I have to conclude that this functionality is undocumented at best and may not even be available in Java NIO. Therefore, anyone who wants to create EPUB files, like me, will have to continue to use the old ZipFile API. An alternative is to use a zip shell created using ZipFile or another language, and then switch to NIO. Both of these options - as I can say - are somewhat inelegant. I thought it was accepted for java.io.File that over time it became obsolete.

+1
source share

All Articles