【问题标题】:Why is my SharpZipLib ZipEntry.Comment not getting set (or read)?为什么我的 SharpZipLib ZipEntry.Comment 没有设置(或读取)?
【发布时间】:2012-12-10 19:26:00
【问题描述】:

我一直在开发一种工具,该工具使用SharpZipLib 将文件添加到压缩文件中,并针对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 doesn't let you get to the Comment,但我am使用ZipFileZipEntry,所以我不明白为什么它不起作用。

有人有什么想法吗?

AddFileToZip 中稍微奇怪的关闭并重新打开是因为 ZipFile.GetEntry 调用总是失败,大概是因为 ZipEntry 尚未写入文件索引。是的,我的测试文件确实是silver dragon。)

【问题讨论】:

    标签: c# zip sharpziplib


    【解决方案1】:

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

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

    如果我们在源代码中查看here,我们可以看到它仅在内容编辑后才运行更新。唔。我想知道是什么设置的?似乎是罪魁祸首。

    四处搜索,我们发现 the following suspicious comment 附加在一些注释掉的代码中

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      使用 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 那里的良好研究答案,我也尝试了多种方法但无法弄清楚(我可以设置评论并保存,但是当我再读一遍它是空的)。

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

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

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

      【讨论】:

      • 哇。我认为我从未如此简单地更改过底层库。半小时的小调整,它现在正在工作。谢谢! :)
      【解决方案3】:

      代码是公开的,只需要修改这个...在 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));
      }
      

      【讨论】:

        猜你喜欢
        • 2021-10-15
        • 1970-01-01
        • 2011-02-14
        • 2011-10-21
        • 2014-01-03
        • 2012-05-19
        相关资源
        最近更新 更多