7

I try to "wrap" a StreamReader in a class Fichier, with some extra methods and attributes.

I want two things :

  • The StreamReader opens automatically in the Fichier class;
  • The StreamReader opens when we use the overrided method ReadLine, and not before (we need to modify the file before reading it with a StreamReader).

A piece of my code looks like this :

public string ReadLine()
{
    if (Reader == null || ???)
    {
        Reader = new StreamReader(Path);
    }
    return Reader.ReadLine();
}

At ???, I want to check if the StreamReader has been closed. Indeed, if we do :

StreamReader sr = new StreamReader(path);
sr.Close();

sr is not null, but how to check that it is closed, and how to re-open it ?

If you wonder why I need to open and close StreamReader, it is because the Fichier object needs to exist anytime, but the file that it represents needs to be modified several times in an external program.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
Chostakovitch
  • 965
  • 1
  • 9
  • 33
  • 3
    The `System.IO` namespace has a class named `File` so be careful that you don't mix up your own class and the [`System.IO.File`](https://msdn.microsoft.com/en-us/library/system.io.file%28v=vs.110%29.aspx) class. – cbr Apr 20 '15 at 14:38
  • 1
    `.BaseStream.CanRead` perhaps, although explicitly disposing/null would be better. – Alex K. Apr 20 '15 at 14:39
  • I'm French, so my class is "Fichier". I'll edit this, I wanted to be comprehensive but I did the opposite. – Chostakovitch Apr 20 '15 at 14:39
  • You just shouldn't design a FileStream wrapper that can Close and Reopen its stream. Keep it simpler. This probably is an XY problem. – H H Apr 20 '15 at 15:01

4 Answers4

10

The easiest thing is to Dispose (you really should do that, it closes the stream too) it and set it to null when you close it.

Optionally you could check for EndOfStream, but that requires you to read to the end of the stream.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • Good idea; thank you. Why should I prefer `Dispose` to `Close` ? (according this topic, `Close` calls `Dispose` : http://stackoverflow.com/questions/7524903/should-i-call-close-or-dispose-for-stream-objects ) – Chostakovitch Apr 20 '15 at 14:43
  • 4
    @Chostakovitch: Opinions vary, but my opinion is: if it implements `IDisposable`, call `Dispose`. That is future proof too, because when Microsoft updates it and it does require disposal then, you are safe. – Patrick Hofman Apr 20 '15 at 14:44
4

Just set the reference to null when you close the reader:

sr.Close();
sr = null;

There is no reason to hang on to the stream reader, as you can't reopen it. You have to create a new one to get an open stream reader.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
2

There is no public way to check if stream/reader is closed. Just set reader to null as soon as you closed it:

 Reader.Close();
 reader = null;

Or keep separate flag.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
2

StreamReader.Close() will do a number of things if the leaveOpen flag is set to false, if that is the case then you could check if StreamReader.BaseStream is null.

var stream = File.OpenRead(@"C:\test.xml");

var streamReader = new StreamReader(stream);
Console.WriteLine(streamReader.BaseStream == null);

streamReader.Close();
Console.WriteLine(streamReader.BaseStream == null);

outputs:

False

True

Press any key to continue . . .

Trevor Pilley
  • 16,156
  • 5
  • 44
  • 60
  • Interesting idea. I don't think this behavior is documented, so it would be better to not rely on it. Indeed if one have no control over when reader is disposed this may be an option. Additionally using `StreamReader` specific property will limit options to use other readers instead (i.e. base `TextReader`). – Alexei Levenkov Apr 20 '15 at 15:11