MemoryStream在返回时禁用读取

时间:2012-07-17 18:34:21

标签: c# stream memorystream

在我的程序中,我基本上是在读取文件,对其进行一些处理,然后将其作为内存流传递回主程序,这将由流读取器处理。这将全部由我的主要课程处理。

问题是,当我从另一个类的方法返回内存流时,“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的工作方式以及如何完成我想做的事情?

3 个答案:

答案 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());
    }
}