Java NIO Zip Filesystem equivalent of setMethod() in java.util.zip.ZipEntry

I have some existing code to create zip files in the Epub 2 format, which works correctly.

In trying to update my code to support the Epub 3 format, I thought I would try the Java NIO Zip Filesystem instead of java.util.zip.ZipFile . I am almost there except for one tiny item.

There is a 20 byte mimetype file required by the Epub format which must be put into the zip in uncompressed form. The java.util.zip.ZipEntry api provides setMethod(ZipEntry.STORED) to achieve this.

I cannot find any reference to this in the Java NIO FileSystem API doc. Is there an equivalent of ZipEntry.setMethod() ?

EDIT 1

OK, so I see how to display the attributes, and thank you for that example, but I can't find any doc on how to create an attribute such as (zip:method,0), even on Oracle's own oracle. The NIO enhancements in Java 7 seem to me to have been only about 20% documented. The attributes api doc is very sparse, especially how to create attributes.

The feeling I am starting to get is that the NIO Zip filesystem may not be an improvement 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 post it but it's just a key-value pair (name, value)

This code created the zipFile successfully, but when I open the zipFile with 7zip, I see that the mimetype file was stored in the zip as DEFLATED (8) rather than what I need which is STORED (0). So question is, how do I code the attribute correctly so it stores as STORED.


This is not very well documented but the zip filesystem provider of the JDK supports a FileAttributeView by the name zip .

Here is the code from a zip of mine:

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 is what you want.

So, if you want to change the method, if you have a Path into your zip filesystem, it looks like you can do (UNTESTED!):

Files.setAttribute(thePath, "zip:method", ZipEntry.DEFLATED);

Based on the very interesting reply below, I reread all the API doc available and tried various guesses at setting an attribute. I drew a blank on both. I am forced to draw the conclusion that this functionality is at best undocumented, and maybe even unavailable in Java NIO. So anyone who wants to create files in the EPUB format, as I do, will have to continue using the old ZipFile based API. The alternative is to use a shell zip created with ZipFile or some other language, and then switch to NIO. Both of these options are -- how shall I say -- somewhat inelegant. I thought it was intended for java.io.File to become semi-deprecated over time.

链接地址: http://www.djcxy.com/p/24472.html

上一篇: 如何从WKWebView获取cookies?

下一篇: java.util.zip.ZipEntry中setMethod()的等效Java NIO Zip文件系统