Skip to content
Create a gist now

Instantly share code, notes, and snippets.

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.
: stain@wallE /tmp; echo hello > folder
: stain@wallE /tmp; zip folder
adding: folder (stored 0%)
: stain@wallE /tmp; rm folder ; mkdir folder ; echo hello > folder/child
: stain@wallE /tmp; zip -r folder
adding: folder/ (stored 0%)
adding: folder/child (stored 0%)
: stain@wallE /tmp; unzip -t
testing: folder OK
testing: folder/ OK
testing: folder/child OK
No errors detected in compressed data of
: stain@wallE /tmp/81; unzip ../
Archive: ../
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.
... unzip is more foregiving if I add the folder before the file.
: stain@wallE /tmp/892; unzip ../
Archive: ../
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
import static org.junit.Assert.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static;
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;
public void directoryOrFile() throws Exception {
try (FileSystem fs = tempZipFS()) {
Path folder = fs.getPath("folder");
try {
// 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 {
fail("Should have thrown FileAlreadyExistsException");
} catch (FileAlreadyExistsException ex) {
Path child = folder.resolve("child");
// Look, it's both a file and folder!
// Can this be asserted?
// Yes, if you include the final /
// 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)) {
// 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) {
// We find both!
assertEquals(2, paths.size());
// SO does that mean this is a feature, and not a bug?
public static FileSystem tempZipFS() throws Exception {
zip = Files.createTempFile("test", ".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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.