在Java中压缩时,如何维护文件夹结构?

在Java中压缩时,如何维护文件夹结构?,java,android,zip,Java,Android,Zip,我想压缩一个文件夹,其结构如下: 临时/文件夹1/文件1 临时/文件夹2/文件2 临时/文件3 并准确维护目录结构。 目前,当我压缩它时,我得到一个不维护目录结构的压缩。看起来像这样 文件1 文件2 文件3 我该怎么做才能像所有普通的压缩应用程序那样将文件添加到各自的文件夹中 这是我目前掌握的代码: package com.damastah.deflash; import android.util.Log; import java.io.BufferedInputStream; import

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

临时/文件夹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();
        }

    }
}
package com.damastah.deflash;
导入android.util.Log;
导入java.io.BufferedInputStream;
导入java.io.BufferedOutputStream;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.util.ArrayList;
导入java.util.zip.ZipEntry;
导入java.util.zip.ZipoutStream;
公共类压缩{
专用静态最终整数缓冲区=2048;
私有ArrayList_文件;
私有字符串_zipFile;
公共压缩(ArrayList文件、字符串zipFile){
_文件=文件;
_zipFile=zipFile;
}
public-void-zip(){
试一试{
BufferedInputStream原点=null;
FileOutputStream dest=新的FileOutputStream(_zipFile);
ZipOutputStream out=新ZipOutputStream(新缓冲输出流(
目的地);
字节数据[]=新字节[缓冲区];
Log.e(“Compress-zip”、“test”);
对于(int i=0;i<_files.size();i++){
Log.v(“压缩”,“添加:”+_files.get(i).getAbsolutePath());
FileInputStream fi=新的FileInputStream(_files.get(i)
.getAbsolutePath());
原点=新的BufferedInputStream(fi,缓冲区);
ZipEntry入口;
如果(_files.get(i).getAbsolutePath()包含(“.”)
条目=新的ZipEntry(\u文件
.get(i)
.getAbsolutePath()
.子串(
_files.get(i).getAbsolutePath()
.lastIndexOf(“/”+1));
其他的
entry=newzipentry(_files.get(i).getAbsolutePath());
外出、外出(进入);
整数计数;
while((count=origin.read(数据,0,缓冲区))!=-1){
输出。写入(数据,0,计数);
}
origin.close();
}
out.close();
}捕获(例外e){
e、 printStackTrace();
}
}
}

> > P>我不是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));
在我看来,它删除了文件的路径,只留下文件名(类似于
\u files.get(i).getName()
)。如果这是真的,那么这就是为什么在zip文件中没有文件夹结构。您的意思是zip条目应该只是该文件名,而不包含任何文件夹

所以,如果您希望zip文件包含来自
/my/full/path/to/folder/temp/folder1/file1
类似于
temp/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, ""));
...
String dir=“/my/full/path/to/folder/”;
对于(int i=0;i<_files.size();i++){
...
如果(_files.get(i).getAbsolutePath()包含(“.”){
条目=新的ZipEntry(\u文件
.get(i).getAbsolutePath().replace(dir,”);
...

要指定文件路径,您应该使用嵌套的文件构造函数,而不是文字反斜杠,以保持代码的可移植性。@millimoose谢谢您的提示。每天我都会学到一些新的东西:)对于阅读答案的人来说,这更多的是一个提示,而不是一个更正。实际上,使用文字使代码示例在没有帮助函数的情况下更容易阅读。@Damastah I我不知道你为什么有这个文件夹。可能条目不能以
/
标记开头,而且zip认为有一些空的命名文件夹(这只是一个猜测)。因此,请尝试将第一个
/
从您的条目(如
/folder/whatever
删除到
folder/whatever
)中,并让我知道是否有helped@Damastah我很高兴我能帮上忙。这可能不是因为条目一开始就不能有
/
,而是因为
/
在很多操作系统中都是根目录,所以我之前的评论是这真是一个幸运的机会:)