1

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);
Nicholas Terry
  • 1,812
  • 24
  • 40
  • I've noticed that the files you store in the `ZipFileSystem` might replace existing files. The implementation of file updates in the zfs is not very scalable -- it may cache the entire new file in memory until the zfs is closed. – Hank D May 16 '16 at 02:17

1 Answers1

1

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.

SubOptimal
  • 22,518
  • 3
  • 53
  • 69
  • I understand why zip doesnt support unix-specific flags, but it's still VERY annoying..... Do you know of any libs that do support unix-specific flags? – Nicholas Terry Mar 07 '16 at 18:46