在我的计划,我基本上是读文件,做一些处理,然后将其传递回主程序作为一个MemoryStream,这将是一个StreamReader来处理。 这将全部由我的主要旁的一类进行处理。
问题是,当我在另一个类从我的方法返回的内存流的“的CanRead”变量设置为false,从而导致StreamReader的初始化失败。
下面是发生(尽管在这里我写在其他类中的MemoryStream的问题的一个例子,但它还是引起了当我通过它回到了同样的错误。
在名为“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);
当我把“回归MemStream”断点时,“的CanRead”属性仍设置为true。 一旦我一步,使得它得到回到我的主要功能,并写入返回值Mstream工具时,“的CanRead”属性设置为false。 然后,这导致的StreamReader说Mstream工具无法读取(如物业所示)异常。 该数据是在流缓存所应当的,但我不能把它弄出来。
如何设置它,以便“的CanRead”一旦回到我的主会报告是真的吗? 还是我误解的MemoryStream是如何工作的,我怎么会完成我想做什么?
这就是问题:
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;
}
该StreamWriter
占用内存流的所有权,当using
语句结束时, MemoryStream
也被关闭。
见有什么办法来关闭一个StreamWriter而不关闭其BaseStream? 。
正如其他人所指出的,问题是,当的StreamWriter关闭流被关闭。 一种可能的方式来处理,这是返回一个字节数组,而不是一个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());
}
}
另一种方法是将流复制到另一个流返回之前。 然而,这仍然有后续访问它有一个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());
}
}