7Zipプログラムで作成されたファイルが1つあります。 deflateメソッドを使用して圧縮しました。 Java
に同じアーカイブ(同じMD5sum)を作成します。 Zipファイルを作成するとき、たとえば http://www.kodejava.org/examples/119.html のようにインターネットで見つけたアルゴリズムを使用しましたが、この方法でZipファイルを作成したとき、圧縮されたサイズは、圧縮されていないファイルのサイズよりも大きいので、何が起こっているのでしょうか?これはあまり便利な圧縮ではありません。 7Zipプログラムで作成したZipファイルとまったく同じZipファイルを作成するにはどうすればよいですか?それが役立つ場合は、7Zipプログラムで作成したZipファイルに関するすべての情報があります。
// 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();
}
}
明確にするために、オリジナルに7ZipのZipアルゴリズムを使用しましたか?また、7Zipは、他のベンダーよりも2〜10%圧縮率が高いと主張しています。 Javaに組み込まれているZipアルゴリズムは、7Zipのアルゴリズムほど最適化されていません。同様の圧縮ファイルが必要な場合は、コマンドラインから7Zipを呼び出すのが最善です。 。
Zipファイルを解凍して、その中のファイルを変更し、同じMD5ハッシュになるように再圧縮しようとしていますか?ハッシュは、それを防ぐためのものです。
ZipOutputStreamには、圧縮を調整するメソッドがほとんどありません。
public void setMethod(int method)
後続のエントリのデフォルトの圧縮方法を設定します。このデフォルトは、個々のZipファイルエントリに圧縮方法が指定されておらず、最初はDEFLATEDに設定されている場合に使用されます。
public void setLevel(int level)
DEFLATEDである後続のエントリの圧縮レベルを設定します。デフォルト設定はDEFAULT_COMPRESSIONです。 level-圧縮レベル(0-9)
次のようなものの後に追加する場合:
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(target));
zos.setMethod( ZipOutputStream.DEFLATED );
zos.setLevel( 5 );
...
それはあなたの圧縮を改善しませんか?
絶対パスを渡す関数を次に示します。これは、ディレクトリと同じ名前のZipファイルを作成し(その下ですべてのサブフォルダーとファイルのZip、すべてが!!)、成功時にtrue、例外時にfalseを返します。もしあれば。
public class FileUtil {
final static int BUFFER = 2048;
private static Logger log = Logger.getLogger(FileUtil.class);
public static boolean createZipArchive(String srcFolder) {
try {
BufferedInputStream Origin = null;
FileOutputStream dest = new FileOutputStream(new File(srcFolder+ ".Zip"));
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
byte data[] = new byte[BUFFER];
File subDir = new File(srcFolder);
String subdirList[] = subDir.list();
for(String sd:subdirList)
{
// get a list of files from current directory
File f = new File(srcFolder+"/"+sd);
if(f.isDirectory())
{
String files[] = f.list();
for (int i = 0; i < files.length; i++) {
System.out.println("Adding: " + files[i]);
FileInputStream fi = new FileInputStream(srcFolder + "/"+sd+"/" + files[i]);
Origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(sd +"/"+files[i]);
out.putNextEntry(entry);
int count;
while ((count = Origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
out.flush();
}
}
}
else //it is just a file
{
FileInputStream fi = new FileInputStream(f);
Origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(sd);
out.putNextEntry(entry);
int count;
while ((count = Origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
out.flush();
}
}
}
Origin.close();
out.flush();
out.close();
} catch (Exception e) {
log.info("createZipArchive threw exception: " + e.getMessage());
return false;
}
return true;
}
}
同じソースファイルから2つの同じZipファイル(同じmd5sumを含む)を生成するには、同じZipユーティリティを使用することをお勧めします-常に同じJavaプログラムを使用するか、常に7Zipを使用します。
たとえば、7Zipユーティリティにはalot of options-その多くはカスタマイズ可能な単純なデフォルト(またはリリース間で違いますか?)-およびany Java Zip実装では、これらのオプションも明示的に設定する必要があります。Javaアプリが単に外部「7z」プログラムを呼び出すことができる場合、カスタムJava Zip実装(これは、実装を簡単にスケールアウトできるmap-reduce問題の良い例でもあります。)
しかし、サーバー側で生成されたZipファイルとクライアント側で生成されたZipファイルがある場合に遭遇する主な問題は、Zipファイルが元のファイルだけでなく2つのものを保存することです:(1)ファイル名、および(2)ファイルのタイムスタンプ。これらのいずれかが変更された場合、結果のZipファイルには異なるmd5sumが含まれます。
$ ls tst1/
foo.tar
$ cp -r tst1 tst2
$ ( cd tst1; Zip foo.Zip foo.tar ) ; ( cd tst2; Zip foo.Zip foo.tar ) ; md5sum tst?/foo.Zip
updating: foo.tar (deflated 20%)
updating: foo.tar (deflated 20%)
359b82678a2e17c1ddbc795ceeae7b60 tst1/foo.Zip
b55c33c0414ff987597d3ef9ad8d1d08 tst2/foo.Zip
ただし、「cp -p」を使用して(タイムスタンプを保持):
$ cp -p -r tst1 tst2
$ ( cd tst1; Zip foo.Zip foo.tar ) ; ( cd tst2; Zip foo.Zip foo.tar ) ; md5sum tst?/foo.Zip
updating: foo.tar (deflated 20%)
updating: foo.tar (deflated 20%)
359b82678a2e17c1ddbc795ceeae7b60 tst1/foo.Zip
359b82678a2e17c1ddbc795ceeae7b60 tst2/foo.Zip
Zip内のファイルが同一であっても、ファイル名とパスが異なると同じ問題が発生します。
以下の機能を持つコードを見つけてください 郵便番号 そして unzip。それが誰かを助けることを願っています。
package com.util;
import Java.io.File;
import Java.io.FileInputStream;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.util.ArrayList;
import Java.util.Date;
import Java.util.List;
import Java.util.Zip.ZipEntry;
import Java.util.Zip.ZipInputStream;
import Java.util.Zip.ZipOutputStream;
/**
* @author dinesh.lomte
*
*/
public class ZipUtil {
/**
*
* @param source
* @param destination
*/
public static void unZip(String source, String destination) {
String method = "unZip(String source, String destination)";
ZipInputStream zipInputStream = null;
try {
// Creating the ZipInputStream instance from the source file
zipInputStream = new ZipInputStream(new FileInputStream(source));
// Getting the zipped file list entry
ZipEntry zipEntry = zipInputStream.getNextEntry();
// Iterating through the file list entry
while (zipEntry != null) {
String fileName = zipEntry.getName();
File file = new File(new StringBuilder(destination)
.append(File.separator)
.append(AppUtil.getFileNameWithoutExtension(
AppUtil.getNameFromPath(source)))
.append(File.separator).append(fileName).toString());
// Creating non existing folders to avoid any FileNotFoundException
// for compressed folder
new File(file.getParent()).mkdirs();
FileOutputStream fileOutputStream = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int length;
while ((length = zipInputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, length);
}
fileOutputStream.close();
zipEntry = zipInputStream.getNextEntry();
}
} catch (IOException iOException) {
System.out.println("Failed to unzip the ''{0}'' file located in ''{1}'' folder. Due to, {2}");
} finally {
// Validating if zipInputStream instance in not null
if (zipInputStream != null) {
try {
zipInputStream.closeEntry();
zipInputStream.close();
} catch (IOException iOException) {
}
}
}
}
/**
* Traverse a directory from the source folder location and get all files,
* and add the file into files list.
*
* @param node
*/
public static void generateFileList(
String source, File node, List<String> files) {
// Validating if the node is a file
if (node.isFile()) {
files.add(generateZipEntry(
source, node.getPath().toString()));
}
// Validating if the node is a directory
if (node.isDirectory()) {
String[] subNote = node.list();
for (String filename : subNote) {
generateFileList(source, new File(node, filename), files);
}
}
}
/**
* Format the file path to Zip
* @param source
* @param file
* @return
*/
private static String generateZipEntry(String source, String file) {
return file.substring(source.length(), file.length());
}
/**
*
* @param source
* @param destination
*/
public static void Zip(String source, String destination) {
String method = "Zip(String source, String destination)";
ZipOutputStream zipOutputStream = null;
try {
// Creating the zipOutputStream instance
zipOutputStream = new ZipOutputStream(
new FileOutputStream(destination));
List<String> files = new ArrayList<>();
generateFileList(source, new File(source), files);
// Iterating the list of file(s) to Zip/compress
for (String file : files) {
// Adding the file(s) to the Zip
ZipEntry zipEntry = new ZipEntry(file);
zipOutputStream.putNextEntry(zipEntry);
FileInputStream fileInputStream = new FileInputStream(
new StringBuilder(source).append(File.separator)
.append(file).toString());
int length;
byte[] buffer = new byte[1024];
while ((length = fileInputStream.read(buffer)) > 0) {
zipOutputStream.write(buffer, 0, length);
}
// Closing the fileInputStream instance
fileInputStream.close();
// De-allocating the memory by assigning the null value
fileInputStream = null;
}
} catch (IOException iOException) {
System.out.println("Failed to Zip the file(s) located in ''{0}'' folder. Due to, {1}");
} finally {
// Validating if zipOutputStream instance in not null
if (zipOutputStream != null) {
try {
zipOutputStream.closeEntry();
zipOutputStream.close();
} catch (IOException iOException) {
}
}
}
}
}
package comm;
import Java.io.File;
import Java.io.FileInputStream;
import Java.io.FileOutputStream;*emphasized text*
import Java.io.IOException;
import Java.util.Zip.ZipEntry;
import Java.util.Zip.ZipOutputStream;
public class Zip1 {
public static void main( String[] args )
{
byte[] buffer = new byte[1024];
try{
File f= new File("E:\\");
f.mkdirs();
File origFile= new File(f,"MyZipFile2.Zip");
FileOutputStream fos = new FileOutputStream(origFile);
ZipOutputStream zos = new ZipOutputStream(fos);
ZipEntry ze= new ZipEntry("test.pdf");
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream("D:\\Test.pdf");
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
in.close();
zos.closeEntry();
//remember close it
zos.close();
System.out.println("Done");
}catch(IOException ex){
ex.printStackTrace();
}
}
}