Rajendra's Blog

Wednesday Mar 12, 2008

Zip File System Provider

Recently I worked on developing a sample code called “ZIP File System Provider”. This sample code demonstrates how to develop a file system using the new Java file system interface ( NIO.2 ).

New file system interface is a set of API's which are going to be part of Java SE 7 Platform. These APIs allow us to access the native file system and also provides a service provider interface for pluggable file systems.

ZipProvider is one such pluggable file system to the new file system interface. A new file system can be constructed using a factory method . ZipFileSystem provider defines URI of the form ZIP:///path#pathInZip. Here the 'path' is the path to Zip/Jar file which is located in underlying file system and 'pathInZip' locates an entry inside the Zip. I will give more details about the implementation of ZipProvider in my next blog entry.

The following code lists the top level directories of the zip file books.zip. Suppose books.zip contains the following files (entries)

JavaBooks/RonHichens/JavaNIO.pdf
JavaBooks/HerbertSchildt/cr.pdf
C_Books/DennisRitchie/c.pdf
CtwoPlus/Stroustrap/ctwoplus.pdf
ejb5/BillBurke/ejb.pdf
general/books/xyz.pdf

Then running the following program gives the output:

JavaBooks
C_Books
CtwoPlus
ejb5
general
import java.nio.file.*;
import java.net.URI;
import java.util.Map;
import java.util.Collections;

public class ListZipEntries {

    public static void main(String[] args) throws Exception {
        URI uri = new URI("zip:///C:/zips/books.zip");
        Map <String, ?> env = Collections.emptyMap();
        FileSystem fs = FileSystems.newFileSystem(uri, env);
        // list files in top-level directory of zip file
        Path top = fs.getPath("/");  // # line1 
        DirectoryStream.Filter filter =    DirectoryStreamFilters.newCaseSensitiveGlobFilter("*");
        Files.withDirectory(top,filter, new DirectoryAction() {

            public void invoke(DirectoryEntry entry) {
                System.out.println(entry.getFileName());
            }
        });
    }
}

Run this program placing ZIPProvider jar file in the Java class path. ie. java -cp zipfs.jar ListZipEntries. Modifying the above program by replacing the line1 i.e. “Path path = fs.getPath(“/”)” with “Path path = fs.getPath(“/JavaBooks”);” would result in the following output.

RonHichens
HerbertSchildt

What I am trying to say with this example is, you could traverse the Zip/Jar archive file similar to traversing a directory in the native file system.

Let's assume that we have a Jar file nested inside a Zip. The following program prints the contents of the MANIFEST.MF file which is inside nested jarCompress1.jar file.
import java.io.BufferedInputStream;
import java.nio.file.*;
import java.util.HashMap;
import java.util.Map;

public class ReadEntry {

    public static void main(String... args) throws Exception {
        Path zipfile = Path.get("c:/zips/zip1.zip");
        Map<String, String> env = new HashMap();
        FileSystem manager = FileSystems.newFileSystem(zipfile, env,null);
        Path path = manager.getPath("/jarCompress1.jar/META-INF/MANIFEST.MF");
        System.out.println("Reading input stream");
        BufferedInputStream bis = new BufferedInputStream(path.newInputStream());
        int ch = -1;
        while ((ch = bis.read()) != -1) {
            System.out.print((char) ch);
        }
    }
}

is one more method for creating file systems. This method allows to create a file system from an existing file. In other way, this method allows to view a file as a file system.

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed

Calendar

Feeds

Search

Links

Navigation

Referrers