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

U

U. George

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?
 
A

Andrew Thompson

U. George said:
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
 
U

U. George

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 );
 
R

ricky.clarkson

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

U. George

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.
 
U

U. George

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.
 
R

ricky.clarkson

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

U. George

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.
 
R

ricky.clarkson

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.
 
J

Joseph Dionne

U. George said:
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?

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

U. George

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.


Joseph said:
U. George said:
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?

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
 
J

Joseph Dionne

U. George said:
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.


Joseph said:
U. George said:
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?

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

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

U. George

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?

Joseph said:
U. George said:
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.


Joseph said:
U. George wrote:

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?


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

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
 
J

Joseph Dionne

U. George said:
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?

Joseph said:
U. George said:
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.


Joseph Dionne wrote:

U. George wrote:

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?


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

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

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
 
J

Joseph Dionne

U. George wrote:

[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
 
A

Andrew Thompson

U. George said:

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
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.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top