在我的程序中,我基本上是在读取文件,对其进行一些处理,然后将其作为内存流传递回主程序,这将由流读取器处理。这将全部由我的主要课程处理。
问题是,当我从另一个类的方法返回内存流时,“canread”变量设置为false,从而导致流式读取器初始化失败。
下面是一个问题发生的例子(虽然在这里我正在写另一个类的内存流,但是当我传回它时它仍然会导致相同的错误。
在名为“Otherclass”的类中:
public static MemoryStream ImportantStreamManipulator()
{
MemoryStream MemStream = new MemoryStream();
StreamWriter writer = new StreamWriter(MemStream);
using (writer)
{
//Code that writes stuff to the memorystream via streamwriter
return MemStream;
}
}
函数调用主程序:
MemoryStream MStream = Otherclass.ImportantStreamManipulator();
StreamReader reader = new StreamReader(MStream);
当我在“return MemStream”上放置一个断点时,“CanRead”属性仍然设置为true。一旦我执行它返回到我的main函数,并将返回的值写入MStream,“CanRead”属性设置为false。然后,这会在StreamReader中导致异常,表示无法读取MStream(如指示的属性)。数据应该在流缓冲区中,但我无法理解它。
如何设置它以便“CanRead”在返回主体后报告为true?或者我误解了MemoryStream的工作方式以及如何完成我想做的事情?
答案 0 :(得分:22)
这是问题所在:
using (writer)
{
//Code that writes stuff to the memorystream via streamwriter
return MemStream;
}
你正在关闭作家,关闭了MemoryStream
。在这种情况下,您不希望这样做...虽然您确实需要刷新编写器,然后回滚MemoryStream
。只需将您的代码更改为:
public static MemoryStream ImportantStreamManipulator()
{
// Probably add a comment here stating that the lack of using statements
// is deliberate.
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
// Code that writes stuff to the memorystream via streamwriter
writer.Flush();
stream.Position = 0;
return stream;
}
答案 1 :(得分:2)
StreamWriter
获取内存流的所有权,当using
语句结束时,MemoryStream
也会关闭。
请参阅Is there any way to close a StreamWriter without closing its BaseStream?。
答案 2 :(得分:0)
正如其他人所说,问题是当StreamWriter关闭时Stream将关闭。处理此问题的一种可能方法是返回字节数组而不是MemoryStream。这可以避免可能需要由垃圾收集器处理的长时间运行的对象。
public static void Main()
{
OutputData(GetData());
}
public static byte[] GetData()
{
byte[] binaryData = null;
using (MemoryStream ms = new MemoryStream())
using (StreamWriter sw = new StreamWriter(ms))
{
string data = "My test data is really great!";
sw.Write(data);
sw.Flush();
binaryData = ms.ToArray();
}
return binaryData;
}
public static void OutputData(byte[] binaryData)
{
using (MemoryStream ms = new MemoryStream(binaryData))
using (StreamReader sr = new StreamReader(ms))
{
Console.WriteLine(sr.ReadToEnd());
}
}
另一种方法是在返回之前将Stream复制到另一个流。但是,这仍然存在以下问题:使用StreamReader对其进行后续访问将关闭该流。
public static void RunSnippet()
{
OutputData(GetData());
}
public static MemoryStream GetData()
{
MemoryStream outputStream = new MemoryStream();
using (MemoryStream ms = new MemoryStream())
using (StreamWriter sw = new StreamWriter(ms))
{
string data = "My test data is really great!";
sw.Write(data);
sw.Flush();
ms.WriteTo(outputStream);
outputStream.Seek(0, SeekOrigin.Begin);
}
return outputStream;
}
public static void OutputData(MemoryStream inputStream)
{
using (StreamReader sr = new StreamReader(inputStream))
{
Console.WriteLine(sr.ReadToEnd());
}
}