Reputation: 7585
I have some code that zips up a file sends it over the network and then unzips it on the other end. I'm still testing the code and the source and the destination are the same. Zipping up the file takes on the order of a minute. Unzipping the file takes on the order of an hour. I'm think there must be a flaw in my code to have such a large difference. Here's the code to unzip:
public String uncompressLocalZip(String filename,String strUUID,ParentEntry pe,boolean bControlFileProgress) {
final int BUFFER = 2048;
BufferedOutputStream out = null;
ZipInputStream zis = null;
try {
FileInputStream fis = new FileInputStream(Constants.conf.getFileDirectory() + Constants.PATH_SEPARATOR + strUUID + Constants.PATH_SEPARATOR + filename);
zis = new ZipInputStream(new BufferedInputStream(fis));
ZipEntry entry;
long totallength = 0;
long size = 0;
if (pe !=null)
size = pe.getSize();
while((entry = zis.getNextEntry()) != null) {
System.out.println("Extracting: " +entry);
int count;
byte data[] = new byte[BUFFER];
// write the files to the disk
File fileOutput = new File(Constants.conf.getFileDirectory() + Constants.PATH_SEPARATOR + strUUID + Constants.PATH_SEPARATOR + Constants.conf.getUncompressFolderName() + Constants.PATH_SEPARATOR + entry.getName());
new File(fileOutput.getParent()).mkdirs();
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(fileOutput));
out = new BufferedOutputStream(fos, BUFFER);
while ((count = zis.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
totallength += count;
}
out.flush();
}
}
catch(Exception e) {
e.printStackTrace();
return("FAILED");
}
finally {
try {if ( out!= null) out.close();} catch (IOException ioe) {}
try {if ( zis!= null) zis.close();} catch (IOException ioe) {}
}
return("SUCCESS");
}
Here's the code to zip:
public void createLocalZip(String filename,ProcessEntry pe) {
ZipOutputStream out=null;
try {
File fileOutput = new File (filename);
out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(fileOutput)));
long totallength=0;
long size = pe.getParentEntry().getSize();
String strStartDirectory;
if (pe.getParentEntry().isDirectory())
strStartDirectory=pe.getParentEntry().getUrl();
else
strStartDirectory=pe.getParentEntry().getFolder();
for (int i=0;i<pe.getParentEntry().tableModel3.getRowCount();i++) {
FileEntry fe = pe.getParentEntry().tableModel3.getFileEntry(i);
File fileInput = new File (fe.getUrl());
FileInputStream input = new FileInputStream(fileInput);
BufferedInputStream in = new BufferedInputStream(input);
String strRelativeDir = fe.getUrl().substring(strStartDirectory.length()+1,fe.getUrl().length());
ZipEntry entry = new ZipEntry(strRelativeDir);
out.putNextEntry(entry);
byte[] bbuf = new byte[2048];
int length=0;
while ((in != null) && ((length = in.read(bbuf)) != -1)) {
out.write(bbuf,0,length);
totallength += length;
pe.setProgress((int) (totallength*100/size));
}
in.close();
}
}
catch (Exception e) {
System.out.println(e.getMessage());
}
finally {
try {if (out!=null) out.close();} catch(IOException ioe){}
}
}
Update: The compression ratio for this particular test is about 90% (1.2GB down to about 100MB). So I suppose it could be the extra writing to disk for unzipping vs. zipping, although I would expect close to a 10X differential vs 60X.
Upvotes: 2
Views: 978
Reputation: 7546
Consider using a specialized library to do the zipping/unzipping. http://sevenzipjbind.sourceforge.net/ might help.
Upvotes: 0
Reputation: 53694
don't double wrap your OutputStream with BufferedOutputStream (you only need 1 BufferedOutputStream wrapper), and close it after you are done writing to it.
also, ZipEntry
s can be directories, so check that and handle accordingly.
Upvotes: 2
Reputation: 74750
I have no really big file to test your code, so I can only guess.
You say your uncompressed zip size is more than 1 GB. This could be more than fits in your memory, and if something forces the VM to fit everything in memory, it will have to swap. Observe your program with a profiler.
Make sure your close each FileOutputStream after writing to it. (You create lots of them, and only close the last one.)
I'm not sure about the ZipInputStream implementation (maybe it forces your BufferedStream to buffer much of data). You could try ZipFile
instead (which allows random access, basically).
Upvotes: 0