我一直在研究一种使用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.Comment
,ZipInputStream
doesn't let you get to the Comment
,但我我使用{ {1}}和ZipFile
,所以我不明白为什么它不起作用。
有没有人有任何想法?
(ZipEntry
中略微奇怪的关闭并重新打开是因为AddFileToZip
调用总是失败,大概是因为ZipFile.GetEntry
尚未写入文件索引。是的,我的测试文件确实是silver dragon。)
答案 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));
}