andrea
andrea

Reputation: 1358

StreamReader cannot read from disposed object

I'm using StreamReader, but if try to read from the same stream using two StreamReader-objects I get an error saying I can't read from dispose object (reader3.ReadLine). Since I'm not disposing any object, what am I doing wrong?

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();

Upvotes: 1

Views: 2610

Answers (2)

Richard
Richard

Reputation: 109140

When you read to the end of reader2 you are really reading to the end of the underlying stream (responseStream2). At this point another read from that stream will fail.

While the specific exception is slightly expected, wrapping the same stream in different StreamReaders is going to do weird things because it is a weird thing to do.

If you need to read a stream twice you need to either use a stream that supports resetting its position to the beginning (ie. random access) and then create a new reader for the second read; or (as would seem likely in this case: I doubt any network stream will support random access) buffer the stream content yourself.

Upvotes: 3

Kami
Kami

Reputation: 19447

When you call ReadToEnd() the underlying steam is all read into memory and you have reached the end.

Each time you call the function ReadLine() then underlying stream is moved to the next line.

This means that when your application reaches Reader3.ReadLine() loop, as you have already reached the end of the file, the reader fails.

If the expected file stream is not too large, I would suggest you assign the result of the ReadToEnd() call to a variable and perform subsequent operations on this variable.

If the stream is large, then try resetting the Position property (provided it is supported - See the docs).

Upvotes: 3

Related Questions