How to convert a InputStream to ZIP format?

user405398 picture user405398 · Nov 11, 2010 · Viewed 25.8k times · Source

I am having a InputStream Object which is actually a zip file. I want to change it back to zip file and save it. I am using DWR's FileTransfer class object to receive the uploaded data from client.

FileTransfer have 3 methods, getInputStream() is one of them. It returns InputStream from FileTransfer object.

In my case, fileTransfer object holds zip file and as well as InputStream object too. I have done, lot of searches in google. But i am not able to find one example, that illustrates InputStream to zip conversion.

Update

String zipName = file.getName();
String zipType = file.getMimeType();
InputStream zipStream = file.getInputStream();
ZipInputStream zis = new ZipInputStream(zipStream);
System.out.println("File Name: "+zipName+"\n"+"File Type: "+zipType);
int c;
File f2 = new File(DATA_STORE_LOC+dat+".zip");
path.setPath2(DATA_STORE_LOC+dat+".zip");
FileOutputStream fos = new FileOutputStream(f2);
ZipOutputStream zos = new ZipOutputStream(fos);
c = zis.read();
System.out.println(c);
while ((c = zis.read(BUFFER)) != -1) {
zos.write(BUFFER, 0, c);
}
zos.close();
zis.close();

I tried this code, by thought of a typical file copy program. I know it is false, just tried. It gives me java.util.zip.ZipException: ZIP file must have at least one entry.

Any suggestion would be really appreciative!!!!!

Answer

extraneon picture extraneon · Nov 11, 2010

See the examples java2s, input and output. If you have more questions feel free to ask them :)

For clarity, in this input example you should do something like:

// FileInputStream fin = new FileInputStream(args[i]);
ZipInputStream zin = new ZipInputStream(ft.getInputStream());

As Don Roby correctly said, if you just want to copy you need not know the file structure and you could use for example static IOUtils.copy(in, out) to copy the file.

Further, if you do wish to extract the ZIP file contents, you should not plainly copy bytes. The ZIP file has a structure, and you extract Entries from the ZIP file, and not just bytes (see the example). Every Entry is a (compressed) file (or the data thereof) with the original name:

ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
  System.out.println("Unzipping " + ze.getName());
  FileOutputStream fout = new FileOutputStream(ze.getName());
  for (int c = zin.read(); c != -1; c = zin.read()) {
  ...

Please note the javadoc of getNextEntry():

Reads the next ZIP file entry and positions the stream at the beginning of the entry data.

This positioning is crucial to get to the zipped file contents, and not the metadata.

And I do believe that you accidentally remove the first int:

c = zis.read(); // removing the first
while ((c = zis.read(BUFFER)) != -1) { // so you start with the second?

I believe you mix 2 idioms:

c = zis.read();
while(c != -1) {
   ...
   c = zis.read();
}

and:

int c;
while ((c = zis.read(BUFFER)) != -1) { // so you start with the second?
  ...
}

I think you can see the difference :)