【问题标题】:Adding files to ZIP file将文件添加到 ZIP 文件
【发布时间】:2012-04-11 10:07:32
【问题描述】:

我正在尝试将一些文件添加到 ZIP 文件中,它会创建文件但不会向其中添加任何内容。 代码 1:

String fulldate = year + "-" + month + "-" + day + "-" + min;

File dateFolder = new File("F:\\" + compname + "\\" + fulldate);
dateFolder.mkdir();

String zipName = "F:\\" + compname + "\\" + fulldate + "\\" + fulldate + ".zip";

zipFolder(tobackup, zipName);

我的功能:

public static void zipFolder(File folder, String name) throws Exception {
    byte[] buffer = new byte[18024];

    ZipOutputStream out = new ZipOutputStream(new FileOutputStream(name));
    FileInputStream in = new FileInputStream(folder);

    out.putNextEntry(new ZipEntry(name));

    int len;

    while((len = in.read(buffer)) > 0) {
        out.write(buffer, 0, len);
    }

    out.closeEntry();
    in.close();
    out.close();
}

编辑:我发现了问题,只是在将文件从 C:\ 驱动器写入 F:\ 驱动器中的 ZIP 时遇到问题

【问题讨论】:

  • 如果要遍历给定文件夹中的文件,请使用 File-object 的 listFiles()-method

标签: java zip directory fileinputstream zipoutputstream


【解决方案1】:

您不能压缩文件夹,只能压缩文件。要压缩文件夹,您必须手动添加所有子文件。我写了这个类来完成这项工作。你可以免费拥有它:)

用法是这样的:

List<File> sources = new ArrayList<File>();
sources.add(tobackup);
Packager.packZip(new File(zipName), sources);

这是课程:

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

public class Packager
{
    public static void packZip(File output, List<File> sources) throws IOException
    {
        System.out.println("Packaging to " + output.getName());
        ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(output));
        zipOut.setLevel(Deflater.DEFAULT_COMPRESSION);

        for (File source : sources)
        {
            if (source.isDirectory())
            {
                zipDir(zipOut, "", source);
            } else
            {
                zipFile(zipOut, "", source);
            }
        }
        zipOut.flush();
        zipOut.close();
        System.out.println("Done");
    }

    private static String buildPath(String path, String file)
    {
        if (path == null || path.isEmpty())
        {
            return file;
        } else
        {
            return path + "/" + file;
        }
    }

    private static void zipDir(ZipOutputStream zos, String path, File dir) throws IOException
    {
        if (!dir.canRead())
        {
            System.out.println("Cannot read " + dir.getCanonicalPath() + " (maybe because of permissions)");
            return;
        }

        File[] files = dir.listFiles();
        path = buildPath(path, dir.getName());
        System.out.println("Adding Directory " + path);

        for (File source : files)
        {
            if (source.isDirectory())
            {
                zipDir(zos, path, source);
            } else
            {
                zipFile(zos, path, source);
            }
        }

        System.out.println("Leaving Directory " + path);
    }

    private static void zipFile(ZipOutputStream zos, String path, File file) throws IOException
    {
        if (!file.canRead())
        {
            System.out.println("Cannot read " + file.getCanonicalPath() + " (maybe because of permissions)");
            return;
        }

        System.out.println("Compressing " + file.getName());
        zos.putNextEntry(new ZipEntry(buildPath(path, file.getName())));

        FileInputStream fis = new FileInputStream(file);

        byte[] buffer = new byte[4092];
        int byteCount = 0;
        while ((byteCount = fis.read(buffer)) != -1)
        {
            zos.write(buffer, 0, byteCount);
            System.out.print('.');
            System.out.flush();
        }
        System.out.println();

        fis.close();
        zos.closeEntry();
    }
}

享受吧!

编辑:要检查程序是否仍然忙,可以添加我用 (*) 标记的三行

编辑 2:尝试新代码。在我的平台上,它运行正确(OS X)。我不确定,但在 Windows 中的 AppData 中的文件可能有一些有限的读取权限。

【讨论】:

  • 谢谢!我看看情况如何!编辑:它看起来不错,它确实压缩了它(:D),但它显然是无效的。错误:压缩(压缩)文件夹“F:\David-PC\2012-03-11-25\2012-03-11-25.zip”无效。
  • 等等 - 嗯,很奇怪。它无缘无故地自动终止。 “完毕。”没有出现。
  • @cheese5505:确保给程序所需的时间。压缩需要一些时间。在尝试打开 zip 之前,请确保应用程序已终止。您可以在压缩循环中添加System.out.print(".");,以查看程序是否仍然忙碌。
  • 嗯,我做到了。我导出它并通过 CMD 运行它,但它突然停止。有时间限制吗?这是它发送的最后一个数据: 离开目录 David/AppData/Local/Apple Computer/QuickTime 添加目录 David/AppData/Local/Apple Computer/WebKit 离开目录 David/AppData/Local/Apple Computer/WebKit 离开目录 David/AppData/Local /Apple 电脑添加目录 David/AppData/Local/Application Data C:\Users\David\Desktop>
  • 你会认为如果java要提供一个zip api,就会有一个像你刚刚写的那样的方法。干得好。
【解决方案2】:

另见ZeroTurnaround's Zip library。它具有以下特点(引用):

  • 递归地打包和解包目录
  • 遍历 ZIP 条目

【讨论】:

  • 它在 9 年前没坏过 ;)
【解决方案3】:

我将使用 Java 7 NIO FileSystem 添加另一种方式。它使用了 JAR 文件实际上是 ZIP 的事实:

static public void addToZip(Path zip, Path file) throws IOException {
    Map<String,String> env = new HashMap<>();
    env.put("create", "false"); // We don't create the file but modify it
    
    URI uri = URI.create("jar:file:"+zip.toString());
    try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
        Path f = zipfs.getPath(file.getFileName().toString());
        Files.copy(file, f, StandardCopyOption.REPLACE_EXISTING);
    }
}

【讨论】:

  • 您的代码无法编译!
  • @Yahya 到底什么不能编译?它确实在我的电脑上编译...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 2013-05-27
  • 1970-01-01
相关资源
最近更新 更多