使用java.util.zip.ZipOutputStream时zip文件中的目录

Bal*_*ala 29 java directory zip

假设我有一个文件t.txt,一个目录t和另一个文件t/t2.txt.如果我使用linux zip实用程序"zip -r t.zip t.txt t",我会得到一个zip文件,其中包含以下条目(unzip -l t.zip):

Archive:  t.zip
  Length     Date   Time    Name
 --------        ----      ----      ----
        9  04-11-09 09:11   t.txt
        0  04-11-09 09:12   t/
      15  04-11-09 09:12   t/t2.txt
 --------                           -------
       24                          3 files
Run Code Online (Sandbox Code Playgroud)

如果我尝试使用java.util.zip.ZipOutputStream复制该行为并为该目录创建zip条目,则java会抛出异常.它只能处理文件.我可以在zip文件中创建/ t2.txt条目并添加使用t2.txt文件内容但我无法创建目录.这是为什么?

Joh*_*ood 45

ZipOutputStream 可以通过/在文件夹名称后面添加正斜杠处理空目录.试试(来自)

public class Test {
    public static void main(String[] args) {
        try {
            FileOutputStream f = new FileOutputStream("test.zip");
            ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(f));
            zip.putNextEntry(new ZipEntry("xml/"));
            zip.putNextEntry(new ZipEntry("xml/xml"));
            zip.close();
        } catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 23

只需浏览java.util.zip.ZipEntry的源代码即可.如果ZipEntry的名称以"/"字符结尾,则将其视为目录.只需在目录名后加上"/".

检查此示例只是为了压缩空目录,http: //bethecoder.com/applications/tutorials/showTutorials.action?tutorialId = Java_ZipUtilities_ZipEmptyDirectory

祝好运.


小智 14

Zip程序的Java程序(文件夹包含空的或完整的)

public class ZipUsingJavaUtil {
    /*
     * Zip function zip all files and folders
     */
    @Override
    @SuppressWarnings("finally")
    public boolean zipFiles(String srcFolder, String destZipFile) {
        boolean result = false;
        try {
            System.out.println("Program Start zipping the given files");
            /*
             * send to the zip procedure
             */
            zipFolder(srcFolder, destZipFile);
            result = true;
            System.out.println("Given files are successfully zipped");
        } catch (Exception e) {
            System.out.println("Some Errors happned during the zip process");
        } finally {
            return result;
        }
    }

    /*
     * zip the folders
     */
    private void zipFolder(String srcFolder, String destZipFile) throws Exception {
        ZipOutputStream zip = null;
        FileOutputStream fileWriter = null;
        /*
         * create the output stream to zip file result
         */
        fileWriter = new FileOutputStream(destZipFile);
        zip = new ZipOutputStream(fileWriter);
        /*
         * add the folder to the zip
         */
        addFolderToZip("", srcFolder, zip);
        /*
         * close the zip objects
         */
        zip.flush();
        zip.close();
    }

    /*
     * recursively add files to the zip files
     */
    private void addFileToZip(String path, String srcFile, ZipOutputStream zip, boolean flag) throws Exception {
        /*
         * create the file object for inputs
         */
        File folder = new File(srcFile);

        /*
         * if the folder is empty add empty folder to the Zip file
         */
        if (flag == true) {
            zip.putNextEntry(new ZipEntry(path + "/" + folder.getName() + "/"));
        } else { /*
                 * if the current name is directory, recursively traverse it
                 * to get the files
                 */
            if (folder.isDirectory()) {
                /*
                 * if folder is not empty
                 */
                addFolderToZip(path, srcFile, zip);
            } else {
                /*
                 * write the file to the output
                 */
                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) {
                    /*
                     * Write the Result
                     */
                    zip.write(buf, 0, len);
                }
            }
        }
    }

    /*
     * add folder to the zip file
     */
    private void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws Exception {
        File folder = new File(srcFolder);

        /*
         * check the empty folder
         */
        if (folder.list().length == 0) {
            System.out.println(folder.getName());
            addFileToZip(path, srcFolder, zip, true);
        } else {
            /*
             * list the files in the folder
             */
            for (String fileName : folder.list()) {
                if (path.equals("")) {
                    addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip, false);
                } else {
                    addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip, false);
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你应该关闭*FileInputStream*. (3认同)

che*_*nop 13

像其他人说这里添加空目录添加"/"到目录名称.注意不要添加File.separator(等于"\"),它实际上将一个空文件添加到zip.

我花了一段时间才明白我的错误是什么 - 希望我能节省一些时间......

  • 是的,你确实为我节省了一些时间。在阅读答案时,我在想“是的!我知道得更好:我将使用 File.Separator 来'便携'并有更好的实现。” 非常感谢。 (2认同)

小智 8

您可以在文件夹名称的末尾添加"/".只需使用以下命令:

zip.putNextEntry(new ZipEntry("xml/"));
Run Code Online (Sandbox Code Playgroud)