在Java中创建zip存档

在Java中创建zip存档,java,zip,Java,Zip,我有一个由7zip程序创建的文件。我用了deflate方法来压缩它。现在我想在java中创建相同的归档(使用相同的MD5sum)。当我创建zip文件时,我使用了我在互联网上找到的算法,但是当我用这种方法创建zip文件时,压缩的大小大于未压缩文件的大小,所以发生了什么?这不是一个非常有用的压缩。那个么我怎样才能创建和我用7zip程序创建的zip文件完全相同的zip文件呢?如果有帮助的话,我有关于我在7zip程序中创建的zip文件的所有信息。只是为了澄清一下,您在7zip中使用了zip算法作为原始文

我有一个由7zip程序创建的文件。我用了deflate方法来压缩它。现在我想在
java
中创建相同的归档(使用相同的MD5sum)。当我创建zip文件时,我使用了我在互联网上找到的算法,但是当我用这种方法创建zip文件时,压缩的大小大于未压缩文件的大小,所以发生了什么?这不是一个非常有用的压缩。那个么我怎样才能创建和我用7zip程序创建的zip文件完全相同的zip文件呢?如果有帮助的话,我有关于我在7zip程序中创建的zip文件的所有信息。

只是为了澄清一下,您在7zip中使用了zip算法作为原始文件?此外,7zip声称其压缩比比其他供应商高2-10%。我大胆猜测,Java中内置的ZIP算法没有7zip中的算法优化。如果需要类似的压缩文件,最好从命令行调用7zip


您是否正在尝试解压缩ZIP文件,更改其中的文件,然后重新压缩它,使其具有相同的MD5哈希?散列是为了阻止您这样做

ZipoutStream有几种方法来调整压缩:

设置默认的压缩方法 以后的条目。此默认值 将在压缩时使用 方法未指定为 单个ZIP文件条目,并且 最初设置为放气

设置的压缩级别 已平仓的后续分录。 默认设置为默认压缩。级别-压缩级别(0-9)

当您在以下内容之后添加时:

ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(target));
zos.setMethod( ZipOutputStream.DEFLATED );
zos.setLevel( 5 );
...

它不改进压缩吗?

要从同一源文件生成两个相同的zip文件(包括相同的md5sum),我建议使用相同的zip实用程序——要么始终使用相同的Java程序,要么始终使用7zip

// 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实用程序有很多选项——其中许多只是可以自定义的默认值(或者不同版本之间有所不同?),任何Java zip实现都必须显式地设置这些选项。如果您的Java应用程序可以简单地调用外部“7z”程序,那么您可能会获得比自定义Java zip实现更好的性能。(这也是map reduce问题的一个很好的例子,您可以轻松地扩展实现。)

但是,如果您有一个服务器端生成的zip文件和一个客户端生成的zip文件,那么您将遇到的主要问题是,除了原始文件之外,zip文件还存储两个内容:(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”(保留时间戳):


不同的文件名和路径也会出现同样的问题,即使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;
}   
  }
公共类FileUtil{
最终静态int缓冲区=2048;
私有静态记录器log=Logger.getLogger(FileUtil.class);
公共静态布尔createZipArchive(字符串文件夹){
试一试{
BufferedInputStream原点=null;
FileOutputStream dest=newfileoutputstream(新文件(srcFolder+“.zip”);
ZipOutputStream out=新的zipoutpstream(新的缓冲输出流(dest));
字节数据[]=新字节[缓冲区];
File subDir=新文件(srcFolder);
字符串subdirList[]=subDir.list();
for(字符串sd:子列表)
{
//从当前目录获取文件列表
文件f=新文件(srcFolder+“/”+sd);
if(f.isDirectory())
{
字符串文件[]=f.list();
对于(int i=0;i
请在下面的代码中找到具有压缩和解压缩功能的代码。希望它能帮助别人

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 com.util;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.Date;
导入java.util.List;
导入java.util.zip.ZipEntry;
导入java.util.zip.ZipInputStream;
导入java.util.zip.ZipoutStream;
/**
*@author dinesh.lomte
*
*/
公共类ZipUtil{
/**
* 
*@param源
*@param destina
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();
            }
        }
}
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) {
                }
            }
        }
    }
}