Java将文件追加到zip压缩包中

4

可能是重复:
使用Java将文件添加到zip文件中

我有一个包含几个文件夹的zip文件,但重要的是dir,里面还有另一个名为folder的文件夹,它包含许多需要更新的文件。

现在我有一个位于zip外部的名为dir的文件夹,其中包含我需要更新的文件的文件夹。因此,路径相同。如何将这些文件更新到zip中?

棘手的地方在于dir位于zip的根目录下,并且它包含许多文件夹,而不仅仅是文件夹。但我只需要更新文件夹中的文件,不能干扰文件夹外但仍在dir中的任何文件。

可以做到吗?我知道可以使用-u修饰符在bash中完成此操作,但如果可能的话,我更喜欢使用java进行此操作。

谢谢您对此问题的帮助

为了更清晰

Zip内部 /dir/folder/filestoupdate

Zip外部 /dir/folder/filestomoveintozip


https://dev59.com/qHE95IYBdhLWcg3wn_f2 - Oleg Mikheev
2个回答

8

好的,这是最终方法,它与我之前在 pastebin 上发布的方法相同,实际上是从 @Qwe 在之前链接中提到的 stackoverflow 主题中获得的,但我添加了路径变量,以便将文件添加到 zip 文件内部的文件夹中。

现在来看看如何在我的示例中使用它。 我想将一个文件添加到另一个文件夹内部的文件夹中,我将使用我在问题中的设置,像这样进行操作:

private void addFilesToZip(File source, File[] files, String path){
    try{
        File tmpZip = File.createTempFile(source.getName(), null);
        tmpZip.delete();
        if(!source.renameTo(tmpZip)){
            throw new Exception("Could not make temp file (" + source.getName() + ")");
        }
        byte[] buffer = new byte[4096];
        ZipInputStream zin = new ZipInputStream(new FileInputStream(tmpZip));
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(source));
        for(int i = 0; i < files.length; i++){
            InputStream in = new FileInputStream(files[i]);
            out.putNextEntry(new ZipEntry(path + files[i].getName()));
            for(int read = in.read(buffer); read > -1; read = in.read(buffer)){
                out.write(buffer, 0, read);
            }
            out.closeEntry();
            in.close();
        }
        for(ZipEntry ze = zin.getNextEntry(); ze != null; ze = zin.getNextEntry()){
            if(!zipEntryMatch(ze.getName(), files, path)){
                out.putNextEntry(ze);
                for(int read = zin.read(buffer); read > -1; read = zin.read(buffer)){
                    out.write(buffer, 0, read);
                }
                out.closeEntry();
            }
        }
        out.close();
        tmpZip.delete();
    }catch(Exception e){
        e.printStackTrace();
    }
}

private boolean zipEntryMatch(String zeName, File[] files, String path){
    for(int i = 0; i < files.length; i++){
        if((path + files[i].getName()).equals(zeName)){
            return true;
        }
    }
    return false;
}

感谢提供链接,最终我成功改进了该方法,使其能够添加非根目录中的文件,现在我感到非常满意。希望这也能帮助其他需要的人。 编辑 我对该方法进行了进一步改进,使其不仅可以将文件追加到zip文件中,还可以更新zip文件中的文件。
使用该方法的方式如下:
File[] files = {new File("/path/to/file/to/update/in")};
addFilesToZip(new File("/path/to/zip"), files, "folder/dir/");

您不应该以 / 开始路径(最后一个变量),因为它在 zip 条目中不是这样列出的。


renameTo在Windows中返回false..有任何想法为什么? - nation best
我在代码的for (ZipEntry ze = zin.getNextEntry(); ze != null; ze = zin.getNextEntry())这一行遇到了问题。看起来ZipInputStreamgetNextEntry()返回的是java.util.zip.ZipEntry,而ZipOutputStreamputNextEntry()方法却需要一个org.apache.tools.zip.ZipEntry类型的参数。我无法对ZipEntry进行转型或更改其类型。我收到的错误信息是:java.lang.ClassCastException: java.util.zip.ZipEntry cannot be cast to org.apache.tools.zip.ZipEntry。有什么建议可以解决这个问题吗? @user577732 - Eda

2
很遗憾,Java不能更新 Zip 文件。14 年前 提出了增强请求 ;-)
您需要将其解压缩到临时文件夹中,添加文件,然后再次压缩它。

我的意思是我已经有了这个方法,它可以让我添加到zip文件中,但它只能让我添加到根目录,但我对Java的掌握还不够好,无法真正改进它,但下面是这个方法的代码 http://pastebin.com/APJWMwc3 - user577732
我提取 ZIP 文件并重新打包的问题是,该 ZIP 文件上有签名,因此在解压缩后重新压缩就不太可能了。 - user577732
看一下链接的问题 - 他们推荐TrueZip - 或许它可以解决你的问题? - Oleg Mikheev
希望我能看一下,谢谢。 - user577732
我用那种方法解决了这个问题,稍微修改了一下,现在它完全按照我的要求工作了。这是一些很酷的东西,所以实际上我们可以使用Java更新zip文件。现在我会分享我的答案并解释我做了什么以及它是如何工作的。 - user577732

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接