类似的问题都不是我想要的!
以下代码有什么问题?
files
是文件内容的文本数组,fileNames
是相应的文件名数组。
此代码总是在使用Save方法的倒数第二行失败,但我看不清为什么要关闭该流!
result = new MemoryStream();
using (ZipFile zipFile = new ZipFile())
{
for (int i = 0; i < files.Count(); i++)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(files[i]);
using (MemoryStream fs = new MemoryStream(bytes))
{
zipFile.AddEntry(fileNames[i], fs);
}
}
zipFile.Save(result);
}
感谢您的帮助 - 在这里绝望!
这是我的解决方案,基于@ spender的第一条评论,尽管他在下面发布的解决方案可能更好。
try
{
result = new MemoryStream();
List<Stream> streams = new List<Stream>();
if (files.Count > 0)
{
using (ZipFile zipFile = new ZipFile())
{
for (int i = 0; i < files.Count(); i++)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(files[i]);
streams.Add(new MemoryStream(bytes));
zipFile.AddEntry(fileNames[i], streams[i]);
}
zipFile.Save(result);
}
}
}
catch (Exception ex)
{
throw;
}
答案 0 :(得分:6)
似乎调用Save
是读取源流的点。这意味着在保存之前必须保持它们不被遮挡。在这种情况下放弃using
语句,因为无法将其范围扩展到循环之外。相反,收集您的IDisposable并在保存完成后处理它们。
result = new MemoryStream();
using (ZipFile zipFile = new ZipFile())
{
List<IDisposable> memStreams = new List<IDisposable>();
try
{
for (int i = 0; i < files.Count(); i++)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(files[i]);
MemoryStream fs = new MemoryStream(bytes);
zipFile.AddEntry(fileNames[i], fs);
memStreams.Add(fs);
}
zipFile.Save(result);
}
finally
{
foreach(var x in memStreams)
{
x.Dispose();
}
}
}
答案 1 :(得分:0)
@spender的答案很合适,但如果我想成为使用模式的同义词的话,我的2美分可以作为
班
public class DisposableBucket : IDisposable
{
readonly List<IDisposable> listOfDisposables = new List<IDisposable>();
public TClass Using<TClass>(TClass disposable) where TClass : IDisposable
{
listOfDisposables.Add(disposable);
return disposable;
}
public void Dispose()
{
foreach (var listOfDisposable in listOfDisposables)
{
listOfDisposable.Dispose();
}
}
}
使用方法
result = new MemoryStream();
using(var bucket = new DisposableBucket())
{
using (var zipFile = new ZipFile())
{
List<IDisposable> memStreams = new List<IDisposable>();
for (int i = 0; i < files.Count(); i++)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(files[i]);
var fs = bucket.Using(new MemoryStream(bytes));
zipFile.AddEntry(fileNames[i], fs);
}
zipFile.Save(result);
}
}