1

我一直在开发一个使用SharpZipLib将文件添加到 zipfile 的工具,并带有针对ZipEntry存储我需要的元数据的注释。(我知道还有其他方法可以处理这些元数据,但如果可以避免的话,我想避免重新构建我的解决方案。)

用于将文件和元数据写入 zipfile 的 [略微简化] 代码如下:

public static void AddFileToZip(string path, Guid metadata)
{
    using (ZipFile zipFile = new ZipFile(__zipName))
    {
        zipFile.BeginUpdate();
        zipFile.Add(path);
        zipFile.CommitUpdate();
        zipFile.Close();
    }
    // Close and reopen the ZipFile so it can find the ZipEntry:
    using (ZipFile zipFile = new ZipFile(__zipName))
    {
        string cleanPath = ZipEntry.CleanName(path);
        zipFile.BeginUpdate();
        zipFile.GetEntry(cleanPath).Comment = metadata.ToString("N");
        zipFile.CommitUpdate();
        zipFile.Close();
    }
}

对此的测试工具,然后读取:

[Test]
public void ArchiveCreationTests()
{
    // Hard-code some variables
    string testFile = @"C:\Users\owen.blacker\Pictures\Ddraig arian.png";
    Guid guid = Guid.NewGuid();

    MyClassName.AddFileToZip(testFile, guid);
    Assert.IsTrue(File.Exists(__zipName), "File does not exist: " + __zipName);

    string cleanName = ZipEntry.CleanName(testFile);
    ZipFile zipfile = new ZipFile(__zipName);
    Assert.GreaterOrEqual(
        zipfile.FindEntry(cleanName, true),
        0,
        "Cannot file ZipEntry " + cleanName);

    ZipEntry zipEntry = zipfile.GetEntry(cleanName);
    StringAssert.AreEqualIgnoringCase(
        guid.ToString("N"),
        zipEntry.Comment,
        "Cannot validate GUID comment.");
}

现在我的 zipfile 正在创建中——它确实包含我的测试图像Ddraig arian.png——ZipEntry成功找到了,但StringAssert调用总是失败。我不完全确定它是因为没有被写入而失败,还是因为没有被读取而失败。

现在我知道您必须使用ZipFile/ZipEntry才能访问ZipEntry.Comment,因为ZipInputStream不会让您Comment访问,但我正在使用ZipFileand ZipEntry,所以我不明白为什么它不起作用。

有没有人有任何想法?

(稍微奇怪的 close-and-reopen inAddFileToZip是因为ZipFile.GetEntry调用总是失败,大概是因为ZipEntry尚未将其写入文件索引。是的,我的测试文件确实是一条银龙。)

4

3 回答 3

3

是的,据我所知,这不会起作用。评论没有被写入,也不会给出库的当前迭代。

我根本没有使用过这个库,但是对源代码做了一些检查:

如果我们在源代码中查看这里,我们可以看到它仅在 contentEdited 时运行更新。唔。我想知道是什么设置的?似乎是罪魁祸首。

环顾四周,我们发现一些注释掉的代码附有以下可疑注释

/* Modify not yet ready for public consumption.
   Direct modification of an entry should not overwrite original data before its read.

通常在源代码中搜索我们会发现在修改条目周围有很多半成品的碎片。

所以基本上我认为你要打的是一个半成品的图书馆,它不能做你想做的事。对不起。:-)

当你第一次添加文件时,一些额外的代码考古学告诉我没有办法写评论,唉。在您提交更新之前,可能通过以某种方式找出 ZipEntry 对象来破解某些东西,但是我是如何逃避的。

于 2012-12-10T20:19:51.153 回答
2

你能使用DotNetZip吗?我发现大部分时间使用起来更容易,我能够让 ZipEntry 评论正常工作,见下文。

使用 DotNetZip:

using (ZipFile zip = new ZipFile(__zipName))
{
    string testFile = @"...";
    ZipEntry newEntry = zip.AddFile(testFile);
    newEntry.Comment = "test";
    zip.Save();
}
using (ZipFile zip = new ZipFile(__zipName))
{
    Console.WriteLine(zip[0].Comment);
}

看来 SharpZipLib 不完全支持ZipEntry.Comment,请参阅@DRMacIver 那里的良好研究答案,我也尝试了多种方法但无法弄清楚(我可以设置评论并保存,但是当我再次阅读时它是空值)。

我不知道为什么它不起作用,但我猜这可能是因为标准 zifiles 不支持对文件的评论,整个 zip 文件只有一个评论。所以我想他们可能会扩展 zip 来支持它,也许他们从未完成它或从未测试过它。

无关,但我会提到我之前做过测试,SharpZipLib 能够实现稍微更好的压缩,但是 DotNetZip 的易用性仍然使它成为我更好的解决方案。

我没有尝试使用 SharpZipLib 来读取使用 DotNetZip 创建的带有工作注释的 zip 文件,以查看读取或写入是否有问题(我对此感到好奇)

于 2012-12-10T21:45:32.430 回答
0

代码是公开的,只需要在 File ZipFile.cs行中进行更改(对我来说是 1810)

此示例适用于 IStaticDataSource ...其他方法更改其他方法:)

/// <summary>
/// Add a file entry with data.
/// </summary>
/// <param name="dataSource">The source of the data for this entry.</param>
/// <param name="entryName">The name to give to the entry.</param>
/// <param name="compressionMethod">The compression method to use.</param>
/// <param name="useUnicodeText">Ensure Unicode used for name/comments for this entry.</param>
/// <param name="comment">Comentario</param>
public void Add(IStaticDataSource dataSource, string entryName,
    CompressionMethod compressionMethod, bool useUnicodeText, string comment)
{
    if (dataSource == null)
    {
        throw new ArgumentNullException("dataSource");
    }

    if (entryName == null)
    {
        throw new ArgumentNullException("entryName");
    }

    CheckUpdating();

    ZipEntry entry = EntryFactory.MakeFileEntry(entryName, false);
    entry.IsUnicodeText = useUnicodeText;
    entry.CompressionMethod = compressionMethod;
    entry.Comment = comment;

    AddUpdate(new ZipUpdate(dataSource, entry));
}
于 2015-05-13T12:32:24.493 回答