如何在Java中压缩目录的内容

如何在Java中压缩目录的内容,java,zip,Java,Zip,我正在使用下面的java,但当它压缩时,它会创建一个目录并压缩该目录中的所有内容。 例如,如果我有一个名为“Directory”的文件夹,并且我想将内容压缩到一个压缩文件中,则在压缩文件中会创建一个文件夹testZip,并在其中包含文件。 我需要压缩文件中的所有文件,而不是父目录中的所有文件。 请帮忙。或者建议是否有其他方法 package folderZip; import java.io.File; import java.io.FileInputStream; import java.i

我正在使用下面的java,但当它压缩时,它会创建一个目录并压缩该目录中的所有内容。 例如,如果我有一个名为“Directory”的文件夹,并且我想将内容压缩到一个压缩文件中,则在压缩文件中会创建一个文件夹testZip,并在其中包含文件。 我需要压缩文件中的所有文件,而不是父目录中的所有文件。 请帮忙。或者建议是否有其他方法

package folderZip;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipFolder {
    public ZipFolder() {  
    }  


    public static void main(String[] args) throws Exception {
        ZipFolder obj = new ZipFolder();
        obj.zipFolder("C:\\Drive\\temp\\testZip","C:\\Drive\\temp\\FolderZiper.zip");       
    }


     public void zipFolder(String srcFolder,
                                 String destZipFile) throws Exception {
        ZipOutputStream zip = null;
        FileOutputStream fileWriter = null;

        fileWriter = new FileOutputStream(destZipFile);
        zip = new ZipOutputStream(fileWriter);

        addFolderToZip("", srcFolder, zip);

        zip.flush();
        zip.close();

    }

    private void addFileToZip(String path, String srcFile,
                                     ZipOutputStream zip) throws Exception {

        File folder = new File(srcFile);
        if (folder.isDirectory()) {
            addFolderToZip(path, srcFile, zip);
        } else {
            byte[] buf = new byte[1024];
            int len;
            FileInputStream in = new FileInputStream(srcFile);
            zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
            while ((len = in.read(buf)) > 0) {
                zip.write(buf, 0, len);
            }
        }
    }

    private void addFolderToZip(String path, String srcFolder,
                                       ZipOutputStream zip) throws Exception {
        File folder = new File(srcFolder);

        for (String fileName : folder.list()) {
            if (path.equals("")) {
                addFileToZip(folder.getName(), srcFolder + "/" + fileName,
                             zip);
            } else {
                addFileToZip(path + "/" + folder.getName(),
                             srcFolder + "/" + fileName, zip);
            }
        }
    }
}

因此,如果我理解正确,您想要的是,它中的所有文件都应该从Zip文件中的“/”开始,而不是Zip文件中出现的目标文件夹

例如,如果你有

FolderToZip/
    TestFile1.txt
    TestFile2.txt
    TestFile3.txt
    SomeSubFolder/
        TestFile4.txt
        TestFile5.txt
        TestFile6.txt
Zip文件的内容应该包含

TestFile1.txt
TestFile2.txt
TestFile3.txt
SomeSubFolder/
    TestFile4.txt
    TestFile5.txt
    TestFile6.txt
为此,您需要保留对“开始”文件夹的引用,并将其路径从您正在添加的文件中删除,以创建
ZipEntry

为了简单起见,我将您的代码改为支持
文件
,而不是
字符串
,这只会使整个事情变得不那么混乱

但是魔法出现在这里

FileInputStream in = new FileInputStream(srcFile);
String name = srcFile.getPath();
name = name.replace(rootPath.getPath(), "");
System.out.println("Zip " + srcFile + "\n to " + name);
zip.putNextEntry(new ZipEntry(name));
rootPath
是初始文件夹(
C:\\Drive\\temp\\testZip“
在您的示例中),
srcFile
是要添加的文件

可运行的示例

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


public class ZipFolder {

    public ZipFolder() {
    }

    public static void main(String[] args) throws Exception {
        ZipFolder obj = new ZipFolder();
        obj.zipFolder(new File("/Users/shanewhitehead/exports"),
                new File("FolderZiper.zip"));
    }

    public void zipFolder(File srcFolder, File destZipFile) throws Exception {
        try (FileOutputStream fileWriter = new FileOutputStream(destZipFile);
                ZipOutputStream zip = new ZipOutputStream(fileWriter)) {

            addFolderToZip(srcFolder, srcFolder, zip);
        }
    }

    private void addFileToZip(File rootPath, File srcFile, ZipOutputStream zip) throws Exception {

        if (srcFile.isDirectory()) {
            addFolderToZip(rootPath, srcFile, zip);
        } else {
            byte[] buf = new byte[1024];
            int len;
            try (FileInputStream in = new FileInputStream(srcFile)) {
                String name = srcFile.getPath();
                name = name.replace(rootPath.getPath(), "");
                System.out.println("Zip " + srcFile + "\n to " + name);
                zip.putNextEntry(new ZipEntry(name));
                while ((len = in.read(buf)) > 0) {
                    zip.write(buf, 0, len);
                }
            }
        }
    }

    private void addFolderToZip(File rootPath, File srcFolder, ZipOutputStream zip) throws Exception {
        for (File fileName : srcFolder.listFiles()) {
            addFileToZip(rootPath, fileName, zip);
        }
    }
}
我还使用

清理了您的资源管理,如何使用此库
然后,您只需将文件夹压缩一行:

ZipUtil.pack(new File("D:\\sourceFolder\\"), new File("D:\\generatedZipFile.zip"));

基本上,如果我理解您的问题,您需要从所需的zip条目名称中去掉“源”文件夹名称。类似于和,然后尝试以下操作:当前文件夹正在“测试”,并创建一个子文件夹“testfolder”。testfolder有多个文件,其中一个是“user-guide.pdf”“。程序应该能够创建一个只包含一个条目user-guide.pdf的ZIP文件夹-输出ZIP文件“MyZip”将只包含一个文件user-guide.pdf。输出zip文件创建在您选择的文件夹中-testing或testfolder。如果您能够做到这一点,那么您可以对正在尝试的应用程序应用相同的逻辑。此外,您还可以使用
文件.walkFileTree
文件访问者
API来浏览文件树并压缩内容。非常感谢,您节省了我的时间:)我刚刚做了一个小修改,在压缩文件中,windows中添加了一个“\”,因此我添加了:name=name.replace(rootPath.getPath(),“”);name=name.substring(1);要删除第一个“\”。不确定它在linux中是否已经正常工作,将进行测试