Creating zip archive in Java
I have one file created by 7zip program. I used deflate method to compress it. Now I want to create the same archive (with the same MD5sum) in java
. When I create zip file, I used the algorithm that I found on the Internet for example http://www.kodejava.org/examples/119.html but when I created zip file with this method the compressed size is higher than size of the uncompressed file so what is going on? This isn't a very useful compression. So how I can create zip file that is exactly same as zip file that I created with 7zip program ? If it helps I have all information about zip file that I created in 7zip program.
// simplified code for zip creation in java
import java.io.*;
import java.util.zip.*;
public class ZipCreateExample {
public static void main(String[] args) throws Exception {
// input file
FileInputStream in = new FileInputStream("F:/sometxt.txt");
// out put file
ZipOutputStream out = new ZipOutputStream(new FileOutputStream("F:/tmp.zip"));
// name the file inside the zip file
out.putNextEntry(new ZipEntry("zippedjava.txt"));
// buffer size
byte[] b = new byte[1024];
int count;
while ((count = in.read(b)) > 0) {
out.write(b, 0, count);
}
out.close();
in.close();
}
}
Just to clarify, you used the ZIP algorithm in 7zip for your original? Also 7zip claims to have a 2-10% better compression ratio than other vendors. I would venture a guess that the ZIP algorithm built into Java is not nearly as optimized as the one in 7zip. Your best best is to invoke 7zip from the command line if you want a similarly compressed file.
Are you trying to unpack a ZIP file, change a file within it, then re-compress it so that it has the same MD5 hash? Hashes are meant to prevent you from doing that.
ZipOutputStream has few methods to tune compression:
public void setMethod(int method)
Sets the default compression method for subsequent entries. This default will be used whenever the compression method is not specified for an individual ZIP file entry, and is initially set to DEFLATED.
public void setLevel(int level)
Sets the compression level for subsequent entries which are DEFLATED. The default setting is DEFAULT_COMPRESSION. level - the compression level (0-9)
When you add after something like:
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(target));
zos.setMethod( ZipOutputStream.DEFLATED );
zos.setLevel( 5 );
...
does not it improve your compression?