为什么我的SharpZipLib ZipEntry.Comment没有设置(或读取)?

时间:2012-12-10 19:26:00

标签: c# zip sharpziplib

我一直在研究一种使用SharpZipLib将文件添加到zip文件的工具,并对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.");
}

现在正在创建我的zip文件 - 它确实包含我的测试图像Ddraig arian.png - ,ZipEntry已成功找到,但StringAssert调用始终失败。我不完全确定它是否失败,因为它不是或者它失败了因为它不是

现在我知道你必须使用ZipFile / ZipEntry访问ZipEntry.CommentZipInputStream doesn't let you get to the Comment,但我使用{ {1}}和ZipFile,所以我不明白为什么它不起作用。

有没有人有任何想法?

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

3 个答案:

答案 0 :(得分:3)

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

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

如果我们在源代码中查看here,我们可以看到它只在contentsEdited中运行更新。嗯。我想知道是什么设置的?似乎可能是罪魁祸首。

搜索我们发现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对象,可能会一起破解某些东西,但是如何避开我。

答案 1 :(得分: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文件,并附带工作评论以查看是否可能是阅读或编写它的问题(我很好奇)

答案 2 :(得分:0)

代码是公开的,只需要更改此文件... 在文件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));
}