NPE
NPE

Reputation: 500357

Reading files from an embedded ZIP archive

I have a ZIP archive that's embedded inside a larger file. I know the archive's starting offset within the larger file and its length.

Are there any Java libraries that would enable me to directly read the files contained within the archive? I am thinking along the lines of ZipFile.getInputStream(). Unfortunately, ZipFile doesn't work for this use case since its constructors require a standalone ZIP file.

For performance reasons, I cannot copy the ZIP achive into a separate file before opening it.

edit: Just to be clear, I do have random access to the file.

Upvotes: 7

Views: 2808

Answers (7)

user8883751
user8883751

Reputation: 1

I think apache commons compress may help you.

There is a class org.apache.commons.compress.archivers.zip.ZipArchiveEntry, which inherit java.util.zip.ZipEntry.

It has a method getDataOffset(), that can get the offset of data stream within the archive file.

Upvotes: 0

Sandro
Sandro

Reputation: 1276

I suggest using TrueZIP, it provides file system access to many kinds of archives. It worked well for me in the past.

Upvotes: 1

Anantha Krishnan
Anantha Krishnan

Reputation: 3088

Check whether zip4j helps you or not.

You can try PartInputStream to read zip file as per your use case.

I think it is better to create temp zip file and then accessing it.

Upvotes: -1

Neet
Neet

Reputation: 4047

I've come up with a quick hack (which needs to get sanitized here and there), but it reads the contents of files from a ZIP archive which is embedded inside a TAR. It uses Java6, FileInputStream, ZipEntry and ZipInputStream. 'Works on my local machine':

final FileInputStream ins = new FileInputStream("archive.tar");
// Zip starts at 0x1f6400, size is not needed
long toSkip = 0x1f6400;
// Safe skipping
while(toSkip > 0)
    toSkip -= ins.skip(toSkip);

final ZipInputStream zipin = new ZipInputStream(ins);
ZipEntry ze;
while((ze = zipin.getNextEntry()) != null)
{
    final byte[] content = new byte[(int)ze.getSize()];
    int offset = 0;
    while(offset < content.length)
    {
        final int read = zipin.read(content, offset, content.length - offset);
        if(read == -1)
            break;
        offset += read;
    }
    // DEBUG: print out ZIP entry name and filesize
    System.out.println(ze + ": " + offset);
}
zipin.close();

Upvotes: 7

Zack Macomber
Zack Macomber

Reputation: 6905

7-zip-JavaBinding is a Java wrapper for the 7-zip C++ library.

The code snippets page in particular has some nice examples including printing a list of items in an archive, extracting a single file and opening multi-part archives.

Upvotes: -1

Puce
Puce

Reputation: 38132

If you're using Java SE 7, it provides a zip fie system which allows you to read/ write files in the zip directly: http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html

Upvotes: 0

Alexei Kaigorodov
Alexei Kaigorodov

Reputation: 13525

1.create FileInputStream fis=new FileInputStream(..);

  1. position it at the start of embedded zipfile: fis.skip(offset);

  2. open ZipInputStream(fis)

Upvotes: 1

Related Questions