Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / January 2006

Tip: Looking for answers? Try searching our database.

Can I open a zip file thats within a jar file?

Thread view: 
U. George - 06 Jan 2006 06:17 GMT
I'd like to open a zip file of sound bites. This zip file is within a
jar file.

The only way (that I see) to open a zip/jar file requires a File, or
String. Apparently you cant open a zipfile by simply doing "new
ZipFile( ZipFile.getInputStream( ZipEntry ))"

Any Hope?
Andrew Thompson - 06 Jan 2006 06:36 GMT
> I'd like to open a zip file of sound bites. This zip file is within a
> jar file.
>
> The only way (that I see) to open a zip/jar file requires a File, or
> String. Apparently you cant open a zipfile by simply doing "new ZipFile(
> ZipFile.getInputStream( ZipEntry ))"

The files in a Zip archive can be accessed individually, just
like the files in a jar file (a specialized form of Zip file).

However, when one archive (the Zip file) is contained within another
archive (the JAR), you can only access the Zip File itself, and you
would need to expand it to disk somewhere before accessing the
*contents* of it.

Inestead, I suggest you put your classes in one jar, your sound bytes
in a separate Zip file, and add the Zip File to the class path of
the application.

HTH

Signature

Andrew Thompson
physci, javasaver, 1point1c, lensescapes - athompson.info/andrew

U. George - 06 Jan 2006 16:24 GMT
Well, java.util.ZipFile et al, is probably what I want to stick with. It
is mostly native. ZipEntries appear to be a 'long' index into a native
directory of zip entries.
Since I want to randomly read each of the sound bites, i think it would
work out much better if the SoundBites.zip file in the jar be copied to
a temp file - once. Then have ZipFile et al efficiently seek to each
sound bite needed.

ZipInputStream, appear(s) to be non-native. its fault is that in order
to read any zip-entry, you have to start reading from the beginning of
the file. This is so *very bad* for randomly accessed pieces of sound.

Maybe JavaSoft will take my RFE seriously, maybe not.

>> I'd like to open a zip file of sound bites. This zip file is within a
>> jar file.
[quoted text clipped - 16 lines]
>
> HTH
ricky.clarkson@gmail.com - 06 Jan 2006 16:30 GMT
I think the name ZipFile suggests a real file, not an InputStream.

Do you actually have a performance problem with ZipInputStream, or are
you assuming that native is faster?

JNI has its own overhead.

> in order
> to read any zip-entry, you have to start reading from the beginning of
> the file

I don't see any evidence of that.

Cheers.
U. George - 06 Jan 2006 16:47 GMT
ur not suggesting that the soundbite.zip file within the jar file is not
a real file?

try reading, for example, "Honk.wav" 5 times. Lets also presume that
"Honk.wav" is the last entry in the zip file. To get to that entry u
have to read all the previous entries. To re-read Honk.wav u need to
rewind to beginning, and process all over again.

I am assuming that the native routines actually know how to do an
'lseek', whereas ZipInputStream does not know how to, or can do such things.

> I think the name ZipFile suggests a real file, not an InputStream.
>
[quoted text clipped - 10 lines]
>
> Cheers.
ricky.clarkson@gmail.com - 06 Jan 2006 17:37 GMT
Things inside jar files and zip files are entries, not files.

Seeking within an entry of a jar file or zip file would be slow,
because it's compressed.  It would be better to extract it to a real
file first.

ZipInputStream is appropriate when you want all the entries one after
the other, not when you want to randomly access entries.  InputStreams
in general aren't intended to support random access.
Andrew Thompson - 07 Jan 2006 02:50 GMT
> Well,

Please refrain from top-posting.  I find it most confusing.

>..java.util.ZipFile et al, is probably what I want to stick with. It
> is mostly native. ZipEntries appear to be a 'long' index into a native
[quoted text clipped - 3 lines]
> a temp file - once. Then have ZipFile et al efficiently seek to each
> sound bite needed.

That is one way.  You can also provide it as an add on zip,
or include the sound bytes individually into the jar file.
(As an aside, I do not see any point to 'jar'ing your zip
file.  The end result will probably not offer any compression
advantage over either of the other forms)

> ZipInputStream, appear(s) to be non-native. its fault is that in order
> to read any zip-entry, you have to start reading from the beginning of
> the file.

No. You can get the ZipEntries and randomly access any ZipEntry.
There are a number of ways of accessing Zip files from within Java,
and you are apparently using the sequential one.

Signature

Andrew Thompson
physci, javasaver, 1point1c, lensescapes - athompson.info/andrew

Robert Klemme - 06 Jan 2006 11:26 GMT
> I'd like to open a zip file of sound bites. This zip file is within a
> jar file.
[quoted text clipped - 4 lines]
>
> Any Hope?

http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/ZipInputStream.html

   robert
U. George - 06 Jan 2006 12:32 GMT
OK, How is your link helpfull?

I want to essentially do this:

zf = new ZipFile("foo.jar");
ze = zf.getEntry("SoundBite.zip");

zf2 = new ZipFile( ze );   //<- No constructor for ZipFile(ZipEntry ze)!
ze2 = zf2.getEntry("Horn.wav");
is =  zf2.getInputStream( ze2 );

>>I'd like to open a zip file of sound bites. This zip file is within a
>>jar file.
[quoted text clipped - 8 lines]
>
>     robert
ricky.clarkson@gmail.com - 06 Jan 2006 14:01 GMT
ZipFile has a method called getInputStream(ZipEntry) that returns an
InputStream.

ZipInputStream has a constructor that accepts an InputStream.

Tricky.  But I can do it.  Come back in 7 million years.
U. George - 06 Jan 2006 15:04 GMT
Dont think i'll need to come back in 7 million years. Made a java RFE so
that ZipFile can accept an input stream to a zip conformant file. Maybe
it'll happen in less than 10 years.

BTW: the real trick is in getting SUN/java to impliment the 'WORK' in
directory search, positioning, and rewinding that already exists in the
ZipFile.getInputStream( ZipEntry ); so that I, and others, dont have to
reinvent the same wheel.

> ZipFile has a method called getInputStream(ZipEntry) that returns an
> InputStream.
>
> ZipInputStream has a constructor that accepts an InputStream.
>
> Tricky.  But I can do it.  Come back in 7 million years.
Joseph Dionne - 06 Jan 2006 18:18 GMT
> I'd like to open a zip file of sound bites. This zip file is within a
> jar file.
[quoted text clipped - 4 lines]
>
> Any Hope?

Short answer, no you can't "open" a ZipFile recursively, i.e. a zipped file
within a zipped file (jar).  However, you can read the contents of a zipped
file entry in a jar file using ZipInputStream.  Sample Below.

Create the following files;

File: tZipInJar.java
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class tZipInJar
{
    public static void main(String[] args) throws Exception
    {
        ZipFile         jarFile     = new ZipFile("tZipInJar.jar");
        ZipEntry        jarEntry    = jarFile.getEntry("tZipInJar.zip");
        InputStream     jarIs       = jarFile.getInputStream(jarEntry);
        ZipInputStream  zipIs       = new ZipInputStream(jarIs);
        ZipEntry        zipEntry    = zipIs.getNextEntry();
        long            size        = zipEntry.getSize();
        BufferedReader  br          = new BufferedReader(
            new InputStreamReader(jarFile.getInputStream(zipEntry)));

        while(0 < size)
        {
            String line = null;

            try {
                line = br.readLine();
                size -= line.length();
                System.out.println(line);
            } catch (Exception ex) {
                size = 0;
            }
        }

        br.close();
        zipIs.close();
        jarFile.close();
    }
}

File: tZipInJar.zip
command line: zip tZipInJar.zip tZipInJar.java

Compile tZipInJar.java, build a jar file containing the class and the zip file
created from the source and run the jar application.  This example is
simplistic, and cludgy but it works.

Joseph
U. George - 06 Jan 2006 19:04 GMT
your example is incomplete.  It does not read anything other than the
first entry in a zipfile.

If u need a particular entry, that u have to do

    while( (zipEntry = zipIs.getNextEntry()).getName().equals("Horn.wav")
== false )
        ;

to first seek to the desired entry. After you have read the contents of
the entry, and closed, you will have to rewind the .zip in order to
reposition to another random zip entry.

Very inefficient.

>> I'd like to open a zip file of sound bites. This zip file is within a
>> jar file.
[quoted text clipped - 60 lines]
>
> Joseph
Joseph Dionne - 06 Jan 2006 19:49 GMT
> your example is incomplete.  It does not read anything other than the
> first entry in a zipfile.
[quoted text clipped - 75 lines]
>>
>> Joseph

For me, it reads the contents of tZipInJar.jar(tZipInJar.zip) line by line,
displaying the java source of the example.

For your use, I suspect you will read size bytes into a byte array or other
object.

Joseph
U. George - 06 Jan 2006 20:28 GMT
for me it should just read:
 tZipInJar.jar(tZipInJar.zip(FirstEntry.InZipFile)) line by line

but this should (have) cause your example to fail:
    new InputStreamReader(jarFile.getInputStream(zipEntry))

zipEntry is a file descriptor within the zip file. It is not a file
descriptor within the jar file.

u actually got this to work?

>> your example is incomplete.  It does not read anything other than the
>> first entry in a zipfile.
[quoted text clipped - 84 lines]
>
> Joseph
Joseph Dionne - 06 Jan 2006 20:45 GMT
> for me it should just read:
>  tZipInJar.jar(tZipInJar.zip(FirstEntry.InZipFile)) line by line
[quoted text clipped - 96 lines]
>>
>> Joseph

Is your mail address correct? I sent you a new jar to read all entries.
However, you still need to create the wav files (I believe) to play them.  I
do not play sounds in my java stuff.

Joseph
Joseph Dionne - 06 Jan 2006 21:05 GMT
[snip]

> u actually got this to work?

Yes, I use it for binary data often.  I tried to email this new sample, but
alas address is invalid.  So, here is a version of the sample that will
recursively read zipped file entries in a jar(zipped) file, one at a time.
However, I believe you will need to create the wav files locally to play them
in java.

Sample code: tZipInJar.java
import java.io.InputStream;
import java.io.IOException;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class tZipInJar
{
    public static void main(String[] args) throws Exception
    {
        ZipFile         jarFile     = new ZipFile("tZipInJar.jar");
        ZipEntry        jarEntry    = jarFile.getEntry("tZipInJar.zip");
        InputStream     jarIs       = jarFile.getInputStream(jarEntry);
        ZipInputStream  zipIs       = new ZipInputStream(jarIs);

        while(true)
        {
            ZipEntry zipEntry = zipIs.getNextEntry();

                        if (null == zipEntry) break;

            int    size   = (int)zipEntry.getSize();
                        byte[] buffer = new byte[size];

                        zipIs.read(buffer,0,size);
                        System.out.println(zipEntry);
                        System.out.println(new String(buffer));

            // zipIs.closeEntry();
        }
        zipIs.close();
        jarFile.close();
    }
}

Now create three text files:

File.one:
This is the contents of file one

File.two:
This is the contents of file two

File.three:
This is the contents of file three

I use the following manifest to create an excutable jar, called tZipInJar.mf)

Manifest-Version: 1.0
Created-By: Joseph Dionne for 1.4.x and higher
Main-Class: tZipInJar

Next, compile the sample code, create tZipInJar.zip containing the three files
File.one, File.two, and File.three

> zip tZipInJar.zip File.one File.two File.three

Then create an excutable jar file.

jar cmf tZipInJar.mf tZipInJar.jar tZipInJar.class tZipInJar.zip

Run the jar file.

Joseph


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.