1

我正在使用StreamReader,但如果尝试使用两个StreamReader-objects 从同一流中读取,我会收到错误消息 I 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();
4

2 回答 2

3

当您调用ReadToEnd()底层蒸汽时,所有内容都被读入内存并且您已经走到了尽头。

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

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

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

如果流很大,请尝试重置Position属性(如果支持 -请参阅文档)。

于 2013-02-25T11:47:02.127 回答
3

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

虽然可以预料到特定的异常,但将相同的流包装在不同的流中StreamReaders会做一些奇怪的事情,因为这是一件很奇怪的事情。

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

于 2013-02-25T11:49:22.477 回答