内存流 - 无法访问已关闭的流
本文关键字:内存 访问 | 更新日期: 2023-09-27 18:36:26
嗨,为什么using (var sw = new StreamWriter(ms))
返回Cannot access a closed Stream
exception
. Memory Stream
位于此代码之上。
using (var ms = new MemoryStream())
{
using (var sw = new StreamWriter(ms))
{
sw.WriteLine("data");
sw.WriteLine("data 2");
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
Console.WriteLine(sr.ReadToEnd());
}
} //error here
}
修复它的最佳方法是什么?谢谢
这是因为StreamReader
在释放时会自动关闭基础流。using
语句会自动执行此操作。
但是,您正在使用的StreamWriter
仍在尝试处理流(此外,编写器的using
语句现在正在尝试处理StreamWriter
,然后尝试关闭流)。
解决此问题的最佳方法是:不要使用using
,也不要处理StreamReader
和StreamWriter
。看到这个问题。
using (var ms = new MemoryStream())
{
var sw = new StreamWriter(ms);
var sr = new StreamReader(ms);
sw.WriteLine("data");
sw.WriteLine("data 2");
ms.Position = 0;
Console.WriteLine(sr.ReadToEnd());
}
如果你对sw
感到难过,sr
垃圾回收而不在你的代码中被处理(如推荐的那样),你可以做这样的事情:
StreamWriter sw = null;
StreamReader sr = null;
try
{
using (var ms = new MemoryStream())
{
sw = new StreamWriter(ms);
sr = new StreamReader(ms);
sw.WriteLine("data");
sw.WriteLine("data 2");
ms.Position = 0;
Console.WriteLine(sr.ReadToEnd());
}
}
finally
{
if (sw != null) sw.Dispose();
if (sr != null) sr.Dispose();
}
从 .net45 开始,您可以使用 StreamWriter
的 LeaveOpen
构造函数参数,并且仍然使用 using
语句。例:
using (var ms = new MemoryStream())
{
using (var sw = new StreamWriter(ms, leaveOpen:true))
{
sw.WriteLine("data");
sw.WriteLine("data 2");
}
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
Console.WriteLine(sr.ReadToEnd());
}
}
当StreamReader
的using()
结束时,它会释放对象并关闭流,StreamWriter
仍在尝试使用该流。
当它从 using 语句中出来时,将调用 Dispose
方法自动关闭流
请尝试以下操作:
using (var ms = new MemoryStream())
{
var sw = new StreamWriter(ms);
sw.WriteLine("data");
sw.WriteLine("data 2");
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
Console.WriteLine(sr.ReadToEnd());
}
}
问题是这个块:
using (var sr = new StreamReader(ms))
{
Console.WriteLine(sr.ReadToEnd());
}
当StreamReader
关闭时(离开使用后),它也关闭了它的基础流,所以现在MemoryStream
关闭了。当StreamWriter
关闭时,它会尝试将所有内容刷新到MemoryStream
,但它已关闭。
您应该考虑不要将StreamReader
放在使用块中。
您必须使流保持打开状态才能读取它。"流编写器"在完成写入后将其关闭
using (var ms = new MemoryStream())
{
using (var sw = new StreamWriter(ms, leaveOpen: true)))
{
sw.WriteLine("data");
sw.WriteLine("data 2");
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
Console.WriteLine(sr.ReadToEnd());
}
} //error here
}
就我而言(诚然非常晦涩难懂,不太可能经常复制),这导致了问题(此代码与使用 iTextSharp 生成 PDF 有关):
PdfPTable tblDuckbilledPlatypi = new PdfPTable(3);
float[] DuckbilledPlatypiRowWidths = new float[] { 42f, 76f };
tblDuckbilledPlatypi.SetWidths(DuckbilledPlatypiRowWidths);
显然,声明一个 3 单元格/列表,然后只为宽度设置两个 vals 是导致问题的原因。一旦我将"PdfPTable(3)"更改为"PdfPTable(2)",问题就出在对流烤箱上