【问题标题】:How do I maintain folders structure when zipping in Java?在 Java 中压缩时如何维护文件夹结构?
【发布时间】:2012-06-23 21:32:21
【问题描述】:

我想压缩一个结构如下的文件夹:

临时/文件夹1/文件1

临时/文件夹2/文件2

临时/文件3

并准确地维护目录结构。 目前,当我压缩它时,我得到一个不维护目录结构的压缩包。看起来像这样 文件 1 文件2 文件3

我应该如何将文件添加到它们各自的文件夹中,就像所有普通的压缩应用程序一样?

这是我目前的代码:

package com.damastah.deflash;

import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Compress {
    private static final int BUFFER = 2048;

    private ArrayList<File> _files;
    private String _zipFile;

    public Compress(ArrayList<File> files, String zipFile) {
        _files = files;
        _zipFile = zipFile;
    }

    public void zip() {
        try {
            BufferedInputStream origin = null;
            FileOutputStream dest = new FileOutputStream(_zipFile);

            ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
                    dest));

            byte data[] = new byte[BUFFER];
            Log.e("Compress - zip", "test");
            for (int i = 0; i < _files.size(); i++) {
                Log.v("Compress", "Adding: " + _files.get(i).getAbsolutePath());
                FileInputStream fi = new FileInputStream(_files.get(i)
                        .getAbsolutePath());
                origin = new BufferedInputStream(fi, BUFFER);
                ZipEntry entry;
                if (_files.get(i).getAbsolutePath().contains("."))
                    entry = new ZipEntry(_files
                            .get(i)
                            .getAbsolutePath()
                            .substring(
                                    _files.get(i).getAbsolutePath()
                                            .lastIndexOf("/") + 1));
                else
                    entry = new ZipEntry(_files.get(i).getAbsolutePath());
                out.putNextEntry(entry);

                int count;
                while ((count = origin.read(data, 0, BUFFER)) != -1) {
                    out.write(data, 0, count);
                }

                origin.close();
            }

            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

【问题讨论】:

    标签: java android zip


    【解决方案1】:

    我不是 Android 开发人员,因此请将此代码仅视为提示

    class ZipCompress {
        public static void main(String[] args) throws IOException {
    
            String dir = "d:\\My folder\\";
            // this entries I want to put in archives in the way they are now
            String[] entries = { "temp\\folder1\\file1.txt", "temp\\folder2\\file2.txt",
                    "temp\\file3.txt" };
    
            ZipOutputStream zipos = new ZipOutputStream(new BufferedOutputStream(
                    new FileOutputStream(dir + "archive.zip")));
    
            // time to create entries and fill them with data
            for (String entrie : entries) {
                System.out.println("Writing file: " + dir + entrie);
    
                // prepering file stream
                BufferedInputStream fileStream = new BufferedInputStream(
                        new FileInputStream(dir + entrie));
    
    //--------------------------------------------------------------------------
    //          Here we decide how we entry will look like in archive.
    //          We use only part of path from String[] entries
    //          like "temp\\folder1\\file1.txt"
    //--------------------------------------------------------------------------
                ZipEntry newEntry = new ZipEntry(entrie);
    
                newEntry.setComment("comment to entry: " + newEntry);
    
                // now lets put this entry in archive
                zipos.putNextEntry(newEntry);
    
                // lets put data from file to current archive entry
                int c;
                while ((c = fileStream.read()) != -1)
                    zipos.write(c);
                fileStream.close();
            }
            zipos.close();
        }
    }
    

    编辑

    我不确定你想在这里做什么

    if (_files.get(i).getAbsolutePath().contains("."))
                        entry = new ZipEntry(_files
                                .get(i)
                                .getAbsolutePath()
                                .substring(
                                        _files.get(i).getAbsolutePath()
                                                .lastIndexOf("/") + 1));
    

    据我所知,它删除了文件路径,只留下文件名(类似于_files.get(i).getName())。如果这是真的,那么这就是您的 zip 文件中没有文件夹结构的原因。您是说 zip 条目应该只是那个文件名,没有任何文件夹。

    因此,如果您希望 zip 文件包含来自 /my/full/path/to/folder/temp/folder1/file1temp/folder1/file1 一样,只是在创建 ZipEntry 时删除该路径中不必要的部分

    String dir = "/my/full/path/to/folder/";
    for (int i = 0; i < _files.size(); i++) {
    ...
        if (_files.get(i).getAbsolutePath().contains(".")) {
            entry = new ZipEntry(_files
                .get(i).getAbsolutePath().replace(dir, ""));
    ...
    

    【讨论】:

    • 要指定文件路径,您应该使用嵌套的 File 构造函数或File.separator,而不是文字反斜杠,以保持代码可移植性。
    • @millimoose 感谢您的提示。每天我都会学到一些新东西:)
    • 对于任何阅读答案的人来说,更多的是提示而不是真正的更正,使用文字使代码示例在没有帮助函数的情况下更易于阅读。
    • @Damastah 我不知道你为什么有这个文件夹。也许条目不能以/ 开头标记和 zip 认为有一些空的命名文件夹拳头(这只是一个疯狂的猜测)。因此,请尝试从您的条目中删除第一个 /,例如 /folder/whateverfolder/whatever,如果这有帮助,请告诉我
    • @Damastah 我很高兴能帮上忙。也可能不是因为条目开头不能有/,而是因为/是很多操作系统的根目录,所以我之前的评论真的很幸运:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    相关资源
    最近更新 更多