如何防止意外处置 Streams? (StreamReader, FileStream...)

How do I prevent an unexpected disposal of Streams? (StreamReader, FileStream...)

我有一些代码,我试图在从主机下载大型机文件之前读取其中的一行。我创建了一个 Stream class 的实例作为一个名为 reader 的对象,从主机检索 FTP 数据流并将其放入 Stream 对象,然后创建原始副本Stream 对象及其数据到另一个名为 readerCopy 的 Stream 对象中。我认为,我的问题是,当我将 readerCopy 传递给从 Stream(RetrieveDateFromFile) 检索一些数据的方法时,readerCopyreader 的资源在方法结束后被丢弃。因此,当我的调用方法稍后尝试使用 reader 时,它会抛出以下内容:

System.ObjectDisposedException: '无法访问已释放的对象。对象名称:'System.Net.Sockets.NetworkStream''

我认为将所有 Stream 对象封装在 using 语句中可以做到这一点,以便在到达这些语句的末尾之前不会释放资源,但看起来它们可能会被释放早点。

我错过了什么?

调用方式:

public void FtpFile()
{   
    // Gets the FTP data stream and stores it into reader, creates a new Stream object called readercopy.
    using (Stream reader = request.GetResponse().GetResponseStream(), readerCopy = new MemoryStream())
    {
        if (reader != null)
        {
            reader.CopyTo(readerCopy);// Copies the original Stream to readerCopy.
            readerCopy.Position = 0;  //Sets the position to be beginning of the Stream.

            SMDPPITrigger trigger = new SMDPPITrigger(); //Custom class

            using (StreamReader fileReader = new StreamReader(readerCopy))
            {
                using (FileStream fileStream = new FileStream(ftpFileDestination, FileMode.Create))
                {
                    if (trigger.CheckIfExists(RetrieveDateFromFile(fileReader)) == false)
                        while (true)
                        {
                            bytesRead = reader.Read(buffer, 0, buffer.Length); //<--- error occurs here.

                            if (bytesRead == 0)
                                break;

                            fileStream.Write(buffer, 0, bytesRead);
                        }
                }
            }
        }
    }
}

从流中检索数据的方法:

public DateTime RetrieveDateFromFile(StreamReader mainframeFile)
{
    string lineParsed = "";
    // StreamReader fileReader = new StreamReader(mainframeFile);

    for (int i = 0; i <= 2; i++)
        switch (i)
        {
            case 2:
                string line = mainframeFile.ReadLine();
                if (line != null)
                {
                    lineParsed = line.Substring(124);
                    break;
                }
                else
                {
                    break;
                }

            default:
            {
                mainframeFile.ReadLine();
                break;
            }
        }

    return DateTime.Parse(lineParsed);
}

我怀疑是以下两行代码导致了问题。

reader.CopyTo(readerCopy);// Copies the original Stream to readerCopy.
readerCopy.Position = 0;  //Sets the position to be beginning of the Stream.

您可以尝试指定要复制到 readerCopy 中的流的长度吗? 例如

reader.CopyTo(readerCopy,124);

结束我的问题的循环。事实证明,问题和解决方案正是@KlausGütter 所说的。使用 reader.CopyTo(readerCopy) 将我的位置设置到流的末尾,我的错误消息不是它已被处理而是没有任何内容可读。使用我复制到的流,readerCopy,解决了我的问题,因为流是可搜索的。