我已经为此头疼了两天。我们使用7ZipSharp从几个源文件(实际上是传入的电子邮件(创建.7z文件。
为了优化应用程序,我想避免硬盘访问,所以我切换到了CompressStreams函数家族。
使用文件名而不是Streams的代码非常有效。当切换到Streams时,只有当CompressionMode=Append时,我才会得到"KeyNotFoundException"。
我的测试代码:
for (var i = 0; i < numFiles; i++)
{
//if(i > 0)
// compressor.CompressionMode = CompressionMode.Append;
Console.WriteLine("Adding copy num " + (i + 1) + " to the archive");
SevenZipUtil.AddStream(File.OpenRead(sampleFile), "email-" + i + ".eml", outFile);
}
助手方法代码:
public static void AddStream(Stream inStream, string fileName, string destinationFile)
{
SevenZipCompressor comp = new SevenZipCompressor();
comp.ArchiveFormat = OutArchiveFormat.SevenZip;
comp.CompressionLevel = CompressionLevel.Ultra;
if(File.Exists(destinationFile))
{
comp.CompressionMode = CompressionMode.Append;
}
FileStream outStream = File.OpenWrite(destinationFile);
comp.DefaultItemName = fileName;
comp.CompressStream(inStream, outStream);
outStream.Flush();
outStream.Close();
}
错误源为文件LibraryManager.cs,方法InArchive,第428行。
if (_inArchives[user][format] == null
总结:
- 附加文件而不是Streams,OK
- 模式下的压缩流=创建,确定
- 之后,模式=追加的CompressStream失败
有没有人在一个.7z文件中添加了几个流的工作代码,或者这可能是我应该发布到SevenZipSharp论坛的一个bug?
谢谢,
CompressStreamDictionary适用于您吗?
void TestZipping()
{
SevenZipCompressor compressor = new SevenZipCompressor
{
ArchiveFormat = OutArchiveFormat.SevenZip,
CompressionLevel = CompressionLevel.Ultra,
};
using (Stream output = File.Open("test.7z", FileMode.CreateNew))
using (Stream file1 = File.Open("test1.txt", FileMode.Open))
using (Stream file2 = File.Open("test2.txt", FileMode.Open))
{
compressor.CompressStreamDictionary(new Dictionary<string, Stream> {{ "test1.txt", file1 }, { "test2.txt", file2 }}, output);
}
}
我怀疑您尝试的方法是在一个流中连续创建几个完整的归档,而不是将文件附加到单个归档中。尽管这也可能是由于缺乏资源管理(您应该使用块来包装这些流的生存期,或者以其他方式正确处理它们(。
流是一种将项目从一个位置获取到另一个位置的方法;它是一种从一个状态移动到另一个状态的行为类型的对象。这意味着它不是一个端点或状态类型的对象。你不能添加到行为,你可以添加到状态。所以,这不是一个bug。
这可能没有帮助。看看是否有某种类型的"内存"文件位置(即内存中的整个文件(,然后将其作为添加的起点。我不确定它是否存在,因为压缩文件可能会变得巨大。