Nicholas Terry
Nicholas Terry

Reputation: 1930

Java ZipFileSystem attributes

So I am using a code VERY similar to the following (pulled from http://fahdshariff.blogspot.com/2011/08/java-7-working-with-zip-files.html):

/**
 * Creates/updates a zip file.
 * @param zipFilename the name of the zip to create
 * @param filenames list of filename to add to the zip
 * @throws IOException
 */
public static void create(String zipFilename, String... filenames)
    throws IOException {

  try (FileSystem zipFileSystem = createZipFileSystem(zipFilename, true)) {
    final Path root = zipFileSystem.getPath("/");

    //iterate over the files we need to add
    for (String filename : filenames) {
      final Path src = Paths.get(filename);

      //add a file to the zip file system
      if(!Files.isDirectory(src)){
        final Path dest = zipFileSystem.getPath(root.toString(),
                                                src.toString());
        final Path parent = dest.getParent();
        if(Files.notExists(parent)){
          System.out.printf("Creating directory %s\n", parent);
          Files.createDirectories(parent);
        }
        Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING);
      }
      else{
        //for directories, walk the file tree
        Files.walkFileTree(src, new SimpleFileVisitor<Path>(){
          @Override
          public FileVisitResult visitFile(Path file,
              BasicFileAttributes attrs) throws IOException {
            final Path dest = zipFileSystem.getPath(root.toString(),
                                                    file.toString());
            Files.copy(file, dest, StandardCopyOption.REPLACE_EXISTING);
            return FileVisitResult.CONTINUE;
          }

          @Override
          public FileVisitResult preVisitDirectory(Path dir,
              BasicFileAttributes attrs) throws IOException {
            final Path dirToCreate = zipFileSystem.getPath(root.toString(),
                                                           dir.toString());
            if(Files.notExists(dirToCreate)){
              System.out.printf("Creating directory %s\n", dirToCreate);
              Files.createDirectories(dirToCreate);
            }
            return FileVisitResult.CONTINUE;
          }
        });
      }
    }
  }
}

When I call the Files.copy() in the visitFile() method, the src has 'rwxr-xr-x' file permissions, and the dest is successfully created. When I unzip the result, the corresponding file has only 'rw-r--r--' permissions. I tried using

Files.copy(src, dest, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING)

but the file still has 'rw-r--r--' permissions... Doing a Files.create() with 'rwxr-xr-x' permissions set has the same result... Any ideas?

EDIT: I tried the following, but i just get an UnsupportedOperationException:

Set<PosixFilePermission> permissions = PosixFilePermissions.fromString("rwxr-xr-x");
Files.setPosixFilePermissions(dest, permissions);

Upvotes: 1

Views: 1695

Answers (1)

SubOptimal
SubOptimal

Reputation: 22963

The ZIP file format by default does not support Unix filesystem features. And the ZIP filesystem provider does at least not support to store Unix file permissions.

// ZIP created with teh Java zipfs
zipinfo foobar.zip

file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
version of encoding software:                   2.0
...
non-MSDOS external file attributes:             000000 hex
MS-DOS file attributes (00 hex):                none

If you create the ZIP file with the Linux version of the Info-ZIP implementation.

file system or operating system of origin:      Unix
version of encoding software:                   3.0
...
apparent file type:                             text
Unix file attributes (100755 octal):            -rwxr-xr-x
MS-DOS file attributes (00 hex):                none

For more information you might have a look into the source of ZipFileSystem.java original source or from the current included in JDK 8 Demos and Samples

edit You could try TrueVFS instead of the zipfs. After a quick check it seems it also do not support the Unix file permissions.

You could use Apache commons compress. Following the javadoc it supports Unix permissions.

from ZipArchiveEntry.setUnixMode

Sets Unix permissions in a way that is understood by Info-Zip's unzip command.

Upvotes: 1

Related Questions