In some code for writing and reading a file first create FileStream object then pass it as an argument to StreamWrite or StreamReader, my question is why they don't just creat StreamWrite or StreamReader ? and does each StreamWrite or StreamReader create FileStream automatically ?
FileStream output=new FileStream(fileName,FileMode.OpenOrCreate,FileAccess.Write);
StreamWriter fileWriter=new StreamWriter(output)
Thanks a lot
You're right, it is possible to instantiate a SteamWriter directly with a FilePath and a FileStream will be created automatically under the hood.
But remember that a StreamWriter is an object that is able to write to any Stream (not just FileStreams); the convenience constructor of creating a FileStream underneath the hood is normally good enough. But if someone has some special need to open up a FileStream with very specific options set, they will first create the FileStream, then pass it to the StreamWriter.
If you want to write or read a file you can use the File class.
File.ReadAllText(path);
File.WriteAllText(path,txt);
File.ReadAllLines(path);
File.WriteAllLines(path,lineArray);
No need to use FileStream..
To answer your question of why StreamWriter and StreamReader need to be passed a FileStream..
So that StreamWriter and StreamReader could be reused..
readStream(new FileStream(path,FileMode.Open));//read file stream
readStream(new NetworkStream(url));//read newtwork stream
readStream(new MemoryStream(object));//read memory stream
public void readStream(StreamReader sr)//general reader method
{
//read stream
}
This method is so general it could read almost any stream thereby reusing the code..
Related
Suppose you have this:
using FileStream fileStream = ...;
fileStream.Write(bytes);
using GZipStream gzipStream = new GZipStream(fileStream, CompressionLevel.Optimal);
gzipStream.Write(bytesToCompress);
Would writing to fileStream first, and then creating a new GZipStream from that stream and then writing bytes to it work?
Do I have to flush fileStream first? Or is this simply unsafe?
Would writing to fileStream first, and then creating a new GZipStream from that stream and then writing bytes to it work?
Yes, that is sort of the point of streams really, that they are chainable. See Compose streams.
Do I have to flush fileStream first? Or is this simply unsafe?
Flush is only necessary when you wish to purge buffers and guarantee that the data are written to the backing store (e.g. the filesystem or network).
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?
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) :
Create FileStream explicitly by yourself and wrap SR around it
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) .
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.
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.
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)
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...
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
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.
What is the difference between using File from using System.IO & StreamWriter from using System.IO?
I am using File.WriteAllLines but in many internet-source-codes they are using:
using (StreamWriter writer = new StreamWriter("important.txt"))
{
writer.Write("Word ");
}
File.WriteAllLines is simply a convenience method that internally uses a StreamWriter, which in turn uses a FileStream to write to the file.
The main difference is that while File.WriteAllLines only writes to files, a StreamWriter can write to any stream, for example a network stream.
Either way works, use what suits you the best.
I have my code like this
IsolatedStorageFileStream ostream = new IsolatedStorageFileStream("Conditions.txt", FileMode.Create, FileAccess.Write, store);
try
{
StreamWriter swi = new StreamWriter(ostream);
swi.WriteLine(System.DateTime.Now.Date.ToString());
swi.Close();
}
This is in a loop, in 2nd iteration when this code runs, streamwriter appends the time to the file, I want it to overwrite.
By giving false as a second parameter i can do that but that works only when we are passing path of the file to stringwriter as first parameter.
Can some one help me with this?
You could try use the CreateNew or Truncate Enum value of the FileMode in the IsolatedStorage Constructor.
http://msdn.microsoft.com/en-us/library/system.io.filemode.aspx
Use FileMode.CreateNew Instead of FileMode.Create. So a new file will be created always.
Write down ostream.Close() or ostream.Dispose() just after swi.Close();
It closes the current stream and releases any resources (such as sockets and file handles) associated with the current stream.
FileStream fs = new FileStream("Myfile.Txt",FileMode.Open,FileAccess.Read);
StreamReader sr= new Streamreader(fs);
sr.BaseStream.Seek(0,SeekOrigin.Begin);
In this Code What is the use of BaseStream in this Code.?
Seek is Method ,
sr is an Object of Class StreamReader
then What is BaseStream
sr.BaseStream returns the underlying stream where the stream reader reads from, you can use this to operate directly on the stream.
In your sample sr.BaseStream and the FileStream fs are the same thing.
More info: http://msdn.microsoft.com/en-us/library/system.io.streamreader.basestream.aspx
Usually though you would like to work with the StreamReader itself, because this abstracts away some of the difficulties when working with streams. If you give an example how you would like to use the stream then I can see if I can give a possibly easier sample using StreamReader
You could have shortened your code:
//FileStream fs = new FileStream("Myfile.Txt",FileMode.Open,FileAccess.Read);
//StreamReader sr= new Streamreader(fs);
StreamReader sr = File.OpenText("Myfile.Txt"); // using-block omitted
sr.BaseStream.Seek(0,SeekOrigin.Begin);
And then you can't use fs anymore. There still is a Stream being created, and BaseStream gives you access.
And note you should be careful to flush the Reader before Seeking on the Stream.