您可以通过打开其流并使用Stream.CopyTo
将源条目内容写入目标条目来迭代源存档中的每个条目。
从C# 8.0
它看起来紧凑并且工作正常:
static void CopyZipEntries(string sourceZipFile, string targetZipFile)
{
using FileStream sourceFS = new FileStream(sourceZipFile, FileMode.Open);
using FileStream targetFS = new FileStream(targetZipFile, FileMode.Open);
using ZipArchive sourceZIP = new ZipArchive(sourceFS, ZipArchiveMode.Read, false, Encoding.GetEncoding(1251));
using ZipArchive targetZIP = new ZipArchive(targetFS, ZipArchiveMode.Update, false, Encoding.GetEncoding(1251));
foreach (ZipArchiveEntry sourceEntry in sourceZIP.Entries)
{
// 'is' is replacement for 'null' check
if (targetZIP.GetEntry(sourceEntry.FullName) is ZipArchiveEntry existingTargetEntry)
existingTargetEntry.Delete();
using (Stream targetEntryStream = targetZIP.CreateEntry(sourceEntry.FullName).Open())
{
sourceEntry.Open().CopyTo(targetEntryStream);
}
}
}
使用早于C# 8.0
版本的它也可以正常工作,但需要更多大括号:
static void CopyZipEntries(string sourceZipFile, string targetZipFile)
{
using (FileStream sourceFS = new FileStream(sourceZipFile, FileMode.Open))
{
using (FileStream targetFS = new FileStream(targetZipFile, FileMode.Open))
{
using (ZipArchive sourceZIP = new ZipArchive(sourceFS, ZipArchiveMode.Read, false, Encoding.GetEncoding(1251)))
{
using (ZipArchive targetZIP = new ZipArchive(targetFS, ZipArchiveMode.Update, false, Encoding.GetEncoding(1251)))
{
foreach (ZipArchiveEntry sourceEntry in sourceZIP.Entries)
{
if (targetZIP.GetEntry(sourceEntry.FullName) is ZipArchiveEntry existingTargetEntry)
{
existingTargetEntry.Delete();
}
using (Stream target = targetZIP.CreateEntry(sourceEntry.FullName).Open())
{
sourceEntry.Open().CopyTo(target);
}
}
}
}
}
}
}
对于单个指定的文件副本,只需将底部部分从foreach
循环替换为 if 条件:
static void CopyZipEntry(string fileName, string sourceZipFile, string targetZipFile)
{
// ...
// It means specified file exists in source ZIP-archive
// and we can copy it to target ZIP-archive
if (sourceZIP.GetEntry(fileName) is ZipArchiveEntry sourceEntry)
{
if (targetZIP.GetEntry(sourceEntry.FullName) is ZipArchiveEntry existingTargetEntry)
existingTargetEntry.Delete();
using (Stream targetEntryStream = targetZIP.CreateEntry(sourceEntry.FullName).Open())
{
sourceEntry.Open().CopyTo(targetEntryStream);
}
}
else
MessageBox.Show("Source ZIP-archive doesn't contains file " + fileName);
}