3

I am little confused between two different constructor of StreamReader class i.e

1.StreamReader(Stream)

I know it takes stream bytes as input but the respective output is same.

here is my code using StreamReader(Stream) contructor

string filepath=@"C:\Users\Suchit\Desktop\p022_names.txt";
using(FileStream fs = new FileStream(filepath,FileMode.Open,FileAccess.Read))
{
     using(StreamReader sw = new StreamReader(fs))
     {
         while(!sw.EndOfStream)
         {
             Console.WriteLine(sw.ReadLine());
         }
     }
}

2. StreamReader(String)

This conrtuctor takes the physical file path,
where our respective file   exists but the output is again same.

Here is my code using StreamReader(String)

string filepath=@"C:\Users\Suchit\Desktop\p022_names.txt";
using (StreamReader sw = new StreamReader(filePath))
{
     while(!sw.EndOfStream)
     {
         Console.WriteLine(sw.ReadLine());
     }
}

So, Which one is better? When and where we should use respective code, so that our code become more optimized and readable?

NASSER
  • 5,900
  • 7
  • 38
  • 57
Himanshu Jain
  • 103
  • 1
  • 9

7 Answers7

4

A class StreamReader (as well as StreamWriter) is just a wrapper for FileStream, It needs a FileStream to read/write something to file.

So basically you have two options (ctor overloads) :

  1. Create FileStream explicitly by yourself and wrap SR around it
  2. Let the SR create FileStream for you

Consider this scenario :

        using (FileStream fs = File.Open(@"C:\Temp\1.pb", FileMode.OpenOrCreate, FileAccess.ReadWrite))
        {
            using (StreamReader reader = new StreamReader(fs))
            {
                // ... read something                       

                reader.ReadLine();

                using (StreamWriter writer = new StreamWriter(fs))
                {
                    // ... write something

                    writer.WriteLine("hello");
                }
            }
        }

Both reader and writer works with the same filestream. Now if we change it to :

        using (StreamReader reader = new StreamReader(@"C:\Temp\1.pb"))
        {
            // ... read something                       

            reader.ReadLine();

            using (StreamWriter writer = new StreamWriter(@"C:\Temp\1.pb"))
            {
                // ... write something

                writer.WriteLine("hello");
            }
        }

System.IOException is thrown "The process cannot access the file C:\Temp\1.pb because it is being used by another process... This is because we try to open file with FileStream2 while we still use it in FileStream1. So generally speaking if you want to open file, perform one r/w operation and close it you're ok with StreamReader(string) overload. In case you would like to use the same FileStream for multiple operations or if by any other reason you'd like to have more control over Filestream then you should instantiate it first and pass to StreamReader(fs) .

Fabjan
  • 13,506
  • 4
  • 25
  • 52
  • i have tried both the above solution and you are right , that latter solution is giving System.IOException , but as we all knows that StreamReader(string) internally convert into FileStream object , so why these error comes. Please explore your explaination little more. – Himanshu Jain Aug 07 '15 at 07:31
  • @HimanshuJain edited my answer. Look you open filestream to a file in Fs1 and try to open second filestream to your file in Fs2 - this is not allowed because file is *busy* with fs1 at that time that's why you get this System.IOException – Fabjan Aug 07 '15 at 07:49
1

Which one is better?

None. Both are same. As the name suggests StreamReader is used to work with streams; When you create an instance of StreamReader with "path", it will create the FileStream internally.

When and where we should use respective code

When you have the Stream upfront, use the overload which takes a Stream otherwise "path".

One advantage of using Stream overload is you can configure the FileStream as you want. For example if you're going to work with asynchronous methods, you need to open the file with asynchronous mode. If you don't then operation will not be truly asynchronous.

When at doubt don't hesitate to check the source yourself.

Community
  • 1
  • 1
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
1

Note that the Stream overload doesn't take a FileStream. This allows you to read data from any sub class of Stream, which allows you to do things like read the result of a web request, read unzipped data, or read decrypted data.

Use the string path overload if you only want to read from a file and you don't need to use the FileStream for anything else. It just saves you from writing a line of code:

using (var stream = File.OpenRead(path))
using (var reader = new StreamReader(stream))
{
    ...
}

File.OpenText also does the same thing.

pmccloghrylaing
  • 1,110
  • 8
  • 12
0

Both are same, just overloads, use one of them according to your need. If you have a local file then you can use StreamReader(string path) otherwise if you have just stream from online or some other source then other overload helps you i-e StreamReader(Stream stream)

NASSER
  • 5,900
  • 7
  • 38
  • 57
0

Well after searching the new open source reference. You can see that the latter internaly expands to the former one. So passing a raw file path into the StreamReader makes him expand it internaly to a FileStream. For me this means, both are equivalent and you can use them as you prefer it.

My personal opinion is to use the latter one, because its less code to write and its more explicit. I don't like the way java is doing it with there thousand bytereader, streamreader, outputreaderreader and so on...

ckruczek
  • 2,361
  • 2
  • 20
  • 23
0

Basically both works same that is doing UTF8Encodeing and use Buffer of 1024 bytes. But The StreamReader object calls Dispose() on the provided Stream object when StreamReader.Dispose is called.

You can refer the following Stream and String

You can use either of them depending on what you have in hand Stream or String file path. Hope this makes it clear

Vijay
  • 176
  • 1
  • 3
  • 12
0

StreamReader(string) is just an overload of StreamReader(Stream).

In the context of your question, you are probably better off using the StreamReader(string) overload, just because it means less code. StreamReader(Stream) might be minutely faster but you have to create a FileStream using the string you could have just put straight into the StreamReader, so whatever benefit you gained is lost.

Basically, StreamReader(string) is for files with static or easily mapped paths (as appears to be the case for you), while StreamReader(Stream) could be thought of as a fallback in case you have access to a file programmatically, but it's path is difficult to pin down.