public
Last active

Not sure if this is a feature or bug in ZipFS.. a path can be both a file and folder at the same time -- kind of.

  • Download Gist
TestZipFS.java
Java
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
import static org.junit.Assert.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
 
import java.net.URI;
import java.nio.file.DirectoryStream;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import org.junit.Test;
 
public class TestZipFS {
private static Path zip;
 
@Test
public void directoryOrFile() throws Exception {
try (FileSystem fs = tempZipFS()) {
Path folder = fs.getPath("folder");
assertFalse(Files.exists(folder));
Files.createFile(folder);
assertTrue(Files.exists(folder));
assertTrue(Files.isRegularFile(folder));
assertFalse(Files.isDirectory(folder));
 
try {
Files.createDirectory(folder);
 
// Disable for now, just to see where this leads
// fail("Should have thrown FileAlreadyExistsException");?
} catch (FileAlreadyExistsException ex) {
}
 
// For some reason the second createDirectory() fails correctly
try {
Files.createDirectory(folder);
fail("Should have thrown FileAlreadyExistsException");
} catch (FileAlreadyExistsException ex) {
}
 
Path child = folder.resolve("child");
Files.createFile(child);
 
// Look, it's both a file and folder!
// Can this be asserted?
assertTrue(Files.isRegularFile(folder));
// Yes, if you include the final /
assertTrue(Files.isDirectory(fs.getPath("folder/")));
// But not the parent
// assertTrue(Files.isDirectory(child.getParent()));
// Or the original Path
// assertTrue(Files.isDirectory(folder));
}
// What if we open it again.. can we find both?
try (FileSystem fs2 = FileSystems.newFileSystem(zip, null)) {
assertTrue(Files.isRegularFile(fs2.getPath("folder")));
assertTrue(Files.isRegularFile(fs2.getPath("folder/child")));
assertTrue(Files.isDirectory(fs2.getPath("folder/")));
 
// We can even list the folder
try (DirectoryStream<Path> s = Files.newDirectoryStream(fs2.getPath("folder/"))) {
boolean found = false;
for (Path p : s) {
found = p.endsWith("child");
}
assertTrue("Did not find 'child'", found);
}
// But if we list the root, do we find "folder" or "folder/"?
Path root = fs2.getRootDirectories().iterator().next();
try (DirectoryStream<Path> s = Files.newDirectoryStream(root)) {
List<String> paths = new ArrayList<>();
for (Path p: s) {
paths.add(p.toString());
}
// We find both!
assertEquals(2, paths.size());
assertTrue(paths.contains("/folder"));
assertTrue(paths.contains("/folder/"));
}
// SO does that mean this is a feature, and not a bug?
}
}
public static FileSystem tempZipFS() throws Exception {
zip = Files.createTempFile("test", ".zip");
Files.delete(zip);
System.out.println(zip);
URI jar = new URI("jar", zip.toUri().toString(), null);
Map<String, Object> env = new HashMap<>();
env.put("create", "true");
return FileSystems.newFileSystem(jar, env);
}
 
}
gistfile1.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
: stain@wallE /tmp; echo hello > folder
: stain@wallE /tmp; zip test.zip folder
adding: folder (stored 0%)
: stain@wallE /tmp; rm folder ; mkdir folder ; echo hello > folder/child
: stain@wallE /tmp; zip -r test.zip folder
adding: folder/ (stored 0%)
adding: folder/child (stored 0%)
 
: stain@wallE /tmp; unzip -t test.zip
Archive: test.zip
testing: folder OK
testing: folder/ OK
testing: folder/child OK
No errors detected in compressed data of test.zip.
 
 
: stain@wallE /tmp/81; unzip ../test.zip
Archive: ../test.zip
extracting: folder
checkdir error: folder exists but is not directory
unable to process folder/.
checkdir error: folder exists but is not directory
unable to process folder/child.
gistfile2.txt
1 2 3 4 5 6 7 8 9 10 11
... unzip is more foregiving if I add the folder before the file.
: stain@wallE /tmp/892; unzip ../test.zip
Archive: ../test.zip
creating: folder/
extracting: folder/child
replace folder? [y]es, [n]o, [A]ll, [N]one, [r]ename: r
new name: folder2
extracting: folder2
 
: stain@wallE /tmp/892; ls
folder folder2

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.