【问题标题】:StreamReader cannot read from disposed objectStreamReader 无法从已处置的对象中读取
【发布时间】:2013-02-10 13:12:47
【问题描述】:

我正在使用StreamReader,但如果尝试使用两个StreamReader-objects 从同一个流中读取,我会收到错误消息,提示我can't read from dispose object (reader3.ReadLine)。 既然我没有处理任何对象,那我做错了什么?

Stream responseStream2;
FtpWebResponse ftpResponse2;

string casefile = CNCElement.ID_CASE_TEST_FILE;
string casepath;
if (FileManager.PathCombine(result, lock_root_folder, casefile, out casepath) == false)
    return false;
if (fm.DownloadFtp(result, casepath, out responseStream2, out ftpResponse2) == false)
    return false;

StreamReader reader2 = new StreamReader(responseStream2);
StreamReader reader3 = new StreamReader(responseStream2);
byte[] contents=null;
//if cycle is not present update case file
//if cycle is present, case file is already correct
if (reader2.ReadToEnd().Contains(cycle) == false)
{
    byte seekcase = CNCElement.ID_CASE.Value;
    int casecount = 1;
    string line;
    using (MemoryStream ms = new MemoryStream())
    {
        while ((line = reader3.ReadLine()) != null
              || casecount <= seekcase)
        {
            if (line.Contains("\"\"") == true)
            {
                if (casecount == seekcase)
                    line = line.Replace("\"\"", "\"" + cycle + "\"");
            }
            byte[] app = StrToByteArray(line);
            ms.Write(app, 0, line.Length);
            contents = ms.ToArray();
        }
    }
}

if (reader2 != null)
    reader2.Close();
if (ftpResponse2 != null)
    ftpResponse2.Close();

【问题讨论】:

  • 在从流中读取之前检查流的有效性...此外,您为什么要从同一个流中读取两次?

标签: c# streamreader


【解决方案1】:

当您读到 reader2 的末尾时,您实际上是在读到底层流 (responseStream2) 的末尾。此时,从该流中的另一次读取将失败。

虽然有些特殊的例外是意料之中的,但将相同的流包装在不同的StreamReaders 中会做一些奇怪的事情,因为这是一件很奇怪的事情。

如果您需要读取一个流两次,您需要使用支持将其位置重置为开头(即随机访问)的流,然后为第二次读取创建一个新的读取器;或者(在这种情况下似乎很可能:我怀疑任何网络流都支持随机访问)自己缓冲流内容。

【讨论】:

    【解决方案2】:

    当你调用ReadToEnd() 时,底层的蒸汽被全部读入内存,你已经到了终点。

    每次调用ReadLine() 函数时,底层流都会移动到下一行。

    这意味着当您的应用程序到达Reader3.ReadLine() 循环时,由于您已经到达文件末尾,读取器将失败。

    如果预期的文件流不是太大,我建议你将ReadToEnd()调用的结果分配给一个变量,然后对该变量执行后续操作。

    如果流很大,请尝试重置 Position 属性(如果支持 - See the docs)。

    【讨论】:

      猜你喜欢
      • 2012-12-14
      • 2011-10-23
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 2020-07-21
      相关资源
      最近更新 更多