如何覆盖现有的zip文件?

7

我已经制作了以下工具方法来压缩我的解决方案中的文件。我认为,每当它生成一个与现有文件同名的.zip归档文件时,它会覆盖它。然而,事实并非如此,会抛出异常,说明该文件已经存在。

public static void CompressFile(string zipName, string filePath, string fileName)
{
    try
    {
        using (ZipArchive archive = ZipFile.Open(zipName, ZipArchiveMode.Create))
        {
            archive.CreateEntryFromFile(filePath, fileName, CompressionLevel.Fastest);
        }
    }
    catch(Exception e)
    {
        _log.Error("Exception Caught: {0}", e.Message);
    }
}

是否有布尔类型的覆盖参数我没有注意到,还是我需要编写一个检查程序来删除同名的预先存在的存档文件?


2
仅允许创建新的存档条目。 - Marc B
3
如果你将mode参数设置为Create,则以FileMode.CreateNew作为文件模式值来打开存档。如果存档已经存在,则会抛出IOException异常。该网址链接是英文的,提供更多相关信息。 - Marc B
3个回答

14
请参考ZipFile.Open文档中的说明:

当您将mode参数设置为Create时,存档以FileMode.CreateNew作为文件模式值打开。如果存档已经存在,则会抛出IOException异常。 当您将mode参数设置为Update时,存档以FileMode.OpenOrCreate作为文件模式值打开。如果存档存在,则会打开该存档。现有条目可以被修改,新条目可以被创建。如果存档不存在,则会创建一个新存档;但是,在Update模式下创建zip存档不如在Create模式下创建高效。

因此,问题归结为底层文件处理。当您使用Create作为ZipArchiveMode时,API隐式尝试创建一个文件而没有处理它已经存在的情况。在您的情况下,Update ZipArchiveMode可能更合适。关于所提到的每个值允许和要求的更多详细信息,请参考FileMode枚举
话虽如此,如果您想要替换现有的存档而不是改变它的内容,您需要检查它的存在并在以Create模式打开存档之前删除它

1
我想到最后会是这种情况,只是好奇是否有一些重载布尔参数我错过了。感谢您详细的回答! - Stavros_S
1
bool zipExists = File.Exists("C:\file.zip"); if(zipExists) File.Delete("C:\file.zip"); - user9737100

3

正如@Dan J在他的答案中提到的那样,您所要做的就是检查文件是否存在,如果不必要,就删除它,然后创建它。下面是一个有效的代码片段。

private void ZipTheFolder() {
    try {
        if (File.Exists(ZipPath)) {
            File.Delete(ZipPath);
        }
        ZipFile.CreateFromDirectory(FolderFromZipLocation, ZipPath);
    }
    catch(Exception ex) {
        throw new CustomConfigurationException($ "Error when zip: {ex.Message}");
    }
}

希望对您有帮助。

2
简单来说,写入zip文件之前先删除它。如果之前不存在,那就没有问题。
为了安全起见,您也可以先创建新的zip文件,然后使用强制命令将其移动到旧文件上。
根据:https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive%28v=vs.110%29.aspx
ZipArchive.Open会向现有的zip归档中添加新文件。始终确保阅读文档以确保使用正确的方法!
Nathan

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