Search code examples
javaapache-commons-vfs

Find files in inner zipfile Commons VFS


Is it possible to use the FileObject::findFiles method or similar to search in ZIP files which are stored in a folder? Or do I have to open the zipfiles by myself?

FileObject root = vfs.resolveFile(file:///home/me/test/vfsdir);
// shows everything except the content of the zip 
FileObject[] allFiles = root.findFiles(Selectors.SELECT_ALL);    
// should contain only the three xmls
FileObject[] xmlFiles = root.findFiles(xmlSelector);

VFS Directory-Tree

/ (root)
/folderwithzips
/folderwithzips/myzip.zip (Zipfile not a folder)
/folderwithzips/myzip.zip/myfile.xml
/folderwithzips/myzip.zip/myfile2.xml
/folderwithzips/other.zip 
/folderwithzips/other.zip/another.xml

Solution

  • Sadly it's not possible to search through the content of zips in a VFS as if they were folders.

    So I have to load every zip manually and execute my selector on the content.

    This small method does the trick for me.

    public static void main(String[] vargs) throws FileSystemException {
        FileSystemManager manager = VFS.getManager();
        FileObject root = manager.resolveFile("/home/me/test/vfsdir");
    
        List<FileObject> files = findFiles(root, new XMLSelector());
        files.stream().forEach(System.out::println);
    }
    
    public static List<FileObject> findFiles(FileObject root,FileSelector fileSelector) throws FileSystemException {
        List<FileObject> filesInDir = Arrays.asList(root.findFiles(fileSelector));
        FileObject[] zipFiles = root.findFiles(new ZipSelector());
    
        FileSystemManager manager = VFS.getManager();
    
        List<FileObject> filesInZips = new ArrayList<>();
        for (FileObject zip: zipFiles){
            FileObject zipRoot = manager.createFileSystem(zip);
            Stream.of(zipRoot.findFiles(fileSelector)).forEach(filesInZips::add);
        }
    
        return Stream.concat(filesInDir.stream(),filesInZips.stream()).collect(Collectors.toList());
    }