Java Forum / General / January 2006
Can I open a zip file thats within a jar file?
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 MagazinesGet 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 ...
|
|
|