Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MemoryStream在返回时禁用读取_C#_Stream_Memorystream - Fatal编程技术网

C# MemoryStream在返回时禁用读取

C# MemoryStream在返回时禁用读取,c#,stream,memorystream,C#,Stream,Memorystream,在我的程序中,我基本上是读取一个文件,对其进行一些处理,然后将其作为内存流传递回主程序,由streamreader处理。这一切都将由我的主服务器旁边的一个类来处理 问题是,当我从另一个类中的方法返回内存流时,“canread”变量设置为false,从而导致streamreader初始化失败 下面是发生问题的一个示例(虽然在这里我正在写入另一个类中的memorystream,但当我将它传回时,它仍然会导致相同的错误) 在名为“Otherclass”的类中: 该函数在主程序中调用: MemorySt

在我的程序中,我基本上是读取一个文件,对其进行一些处理,然后将其作为内存流传递回主程序,由streamreader处理。这一切都将由我的主服务器旁边的一个类来处理

问题是,当我从另一个类中的方法返回内存流时,“canread”变量设置为false,从而导致streamreader初始化失败

下面是发生问题的一个示例(虽然在这里我正在写入另一个类中的memorystream,但当我将它传回时,它仍然会导致相同的错误)

在名为“Otherclass”的类中:

该函数在主程序中调用:

MemoryStream MStream = Otherclass.ImportantStreamManipulator();
StreamReader reader = new StreamReader(MStream);
当我在“return MemStream”上设置断点时,“CanRead”属性仍然设置为true。一旦我执行步骤使其返回到我的主函数,并将返回的值写入MStream,“CanRead”属性设置为false。这会导致StreamReader中出现异常,表示无法读取MStream(如属性所示).数据应该在streams缓冲区中,但我就是拿不出来


我如何设置它以便“可以阅读”一旦返回到我的main,是否会报告true?或者我是否误解了MemoryStream的工作原理以及我将如何完成我想做的事情?

StreamWriter拥有内存流的所有权,并且当
using
语句结束时,
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关闭时,流是关闭的。一种可能的处理方法是返回字节数组而不是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());
    }
}   

Jon,如果
writer
在使用
stream
之前进行了GC,会发生什么情况?@KevinBrock:那么它只是垃圾收集,所有缓冲数据都会丢失。
StreamWriter
没有终结器,AFAIK。确实如此。我认为返回它会在使用之前发送一个非封闭版本,然后再处理streamwriter。我想我在想,返回将返回MemoryStream的副本,而不是出于某种原因的引用。我还认为,通过返回保留ImportantStreamManipulator方法将自动处理streamwriter,因此我不确定这是否可行。streamwriter是否会在稍后的某个时间被处理他通过GC处理程序,还是只有在我处理MemoryStream或关闭程序后才会处理它?@xantam:你不需要处理
StreamWriter
。它没有任何非托管资源。它在最终使用后的任何时候都会被垃圾收集,可能是在
刷新
调用.MemoryStrea之后m、 ToArray()甚至可以在基础流关闭时工作。您无法访问关闭的流,但数据仍然存在。
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());
    }
}