Question:
What is different between FileStream and StreamWriter in .Net?
What context are you supposed to use it? What is their advantage and disadvantage?
Is it possible to combine these two into one?
What is different between FileStream and StreamWriter in dotnet?
A FileStream is a Stream. Like all Streams it only deals with byte[] data.
A StreamWriter : TextWriter is a Stream-decorator. A TextWriter encodes the primitive type like string, int and char to byte[] and then writes hat to the linked Stream.
What context are you supposed to use it? What is their advantage and disadvantage?
You use a bare FileStream when you have byte[] data. You add a StreamWriter when you want to write text. Use a Formatter or a Serializer to write more complex data.
Is it possible to combine these two into one?
Yes. You always need a Stream to create a StreamWriter. The helper method System.IO.File.CreateText("path") will create them in combination and then you only have to Dispose() the outer writer.
FileStream writes bytes, StreamWriter writes text. That's all.
A FileStream is explicitly intended for working files.
A StreamWriter can be used to stream to any type of Stream - network sockets, files, etc.
ScottGu explains the different Stream objects quite nicely here: http://www.codeguru.com/Csharp/Csharp/cs_data/streaming/article.php/c4223
They are two different levels used in outputting information to known data sources.
A FileStream is a type of Stream, which is conceptually a mechanism that points to some location and can handle incoming and/or outgoing data to and from that location. Streams exist for reading/writing to files, network connections, memory, pipes, the console, debug and trace listeners, and a few other types of data sources. Specifically, a FileStream exists to perform reads and writes to the file system. Most streams are pretty low-level in their usage, and deal with data as bytes.
A StreamWriter is a wrapper for a Stream that simplifies using that stream to output plain text. It exposes methods that take strings instead of bytes, and performs the necessary conversions to and from byte arrays. There are other Writers; the other main one you'd use is the XmlTextWriter, which facilitates writing data in XML format. There are also Reader counterparts to the Writers that similarly wrap a Stream and facilitate getting the data back out.
Well, from the MSDN for FileStream:
Exposes a Stream around a file, supporting both synchronous and asynchronous read and write operations.
and the MSDN for StreamWriter:
Implements a TextWriter for writing characters to a stream in a particular encoding.
The most obvious difference is that FileStream allows read/write operations, while StreamWriter is write only.
The StreamWriter page goes on to add:
StreamWriter is designed for character output in a particular encoding, whereas classes derived from Stream are designed for byte input and output.
So a second difference is that FileStream is for bytes, while StreamWriter is for text.
One key difference (in addition to the above comments), could be that FileStream supports random disk access read and writes to any specified FileStream.Position. For large file modifications, that can be invaluable.
Related
What is the easiest way to wrap a forward-only non-seekable source Stream (with CanSeek being false, e.g. an incoming network response) into a Stream that supports seeking, but does only read the same bytes from the source once?
Does .NET Standard (C#) offer any implementation of Stream which can be used for this or do I have to write this functionality by myself?
I can imagine an implementation of Stream which gets the source Stream at construction, reads from it and stores bytes that are read for the first time in a cache or buffer which is then used for each subsequent read of the same bytes.
I don't want to wait for the source Stream to be read completely before accessing the wrapped Stream (because it's very large). Therefore copying the source into a local buffer before accessing the buffer is not what I want.
Is it possible to use a BinaryReader and BinaryWriter at the same time with the same underlying NetworkStream
using a single thread sequentially interlacing reads and writes?
using 1 thread for reading and 1 thread for writing?
(My goal is to simultaneously send and receive data via a TcpClient connection)
So far I've come across two related posts:
One references the NetworkStream docs:
Read and write operations can be performed simultaneously on an instance of the NetworkStream class without the need for synchronization. As long as there is one unique thread for the write operations and one unique thread for the read operations, there will be no cross-interference between read and write threads and no synchronization is required.
The second references the BinaryReader docs:
Using the underlying stream while reading or while using the BinaryReader can cause data loss and corruption. For example, the same bytes might be read more than once, bytes might be skipped, or character reading might become unpredictable.
I'm not 100% sure how to interpret these quotes and I'm not sure which of my 2 cases above are possible if any.
"yes" is the short answer; a NetworkStream essentially acts as a duplex stream, with the read operations completely separate to the write operations. A BinaryReader will only be using the read operations, and BinaryWriter the write operations. Concepts like Length, Position and Seek do not make sense on NetworkStream and are not supported. So: there should be no conflict here using BinaryReader / BinaryWriter. However, at the same time I would probably advise against using them - simply because they usually don't actually add much vs using raw Stream operations, and aren't compatible with arbitrary network protocols. If you're implementing something custom that just uses your code: you'll probably be fine, of course.
The warning about touching the Stream while using BinaryReader/BinaryWriter still very much applies to some other streams - FileStream for example: you could trivially corrupt the data by repositioning the stream while a reader/writer thinks it is in charge - and since there is a single position: this means that reads will impact writes, etc. But: this simply doesn't apply to NetworkStream. In this regard: NetworkStream is the exception, not the rule: in terms of what you usually expect from a Stream, NetworkStream is very unusual.
This question already has answers here:
What is the difference between BufferedStream and MemoryStream in terms of application?
(2 answers)
Closed 5 years ago.
I read that Buffer is a sequence of bytes. But I also read that Stream is also a sequence of bytes. So what is the difference between Stream & Buffer?
As I said in my comment, the nutshell difference between a buffer and a stream is that a stream is a sequence that transfers information from or to a specified source, whereas a buffer is a sequence of bytes that is stored in memory. For example:
FileStream stream = new FileStream("filepath.txt", FileMode.OpenOrCreate);
Opens a stream to a file. That stream can be read from, written to, or both. As it doesn't require any additional memory, it's lightweight and fast, but arbitrarily referencing a particular set of data in the source can be cumbersome. Streams also benefit from being a connection rather than a discrete set of data, so you don't need to know the size of the data beforehand.
Conversely:
byte[] fileContents = File.ReadAllBytes("filepath.txt");
Reads all the bytes of a file into memory. This is handy for when you need to manipulate the entire file at once, or keep a "local copy" for your program to hold onto so the file can be free for other uses. Depending on the size of the source and the amount of available memory, though, a buffer containing the entire file might not be an option.
This is just a barebones explanation, though. There are more thorough ones out there, For example, as Marc Gravell puts it:
Many data-structures (lists, collections, etc) act as containers - they hold a set of objects. But not a stream; if a list is a bucket, then a stream is a hose. You can pull data from a stream, or push data into a stream - but normally only once and only in one direction (there are exceptions of course). For example, TCP data over a network is a stream; you can send (or receive) chunks of data, but only in connection with the other computer, and usually only once - you can't rewind the Internet.
Streams can also manipulate data passing through them; compression streams, encryption streams, etc. But again - the underlying metaphor here is a hose of data. A file is also generally accessed (at some level) as a stream; you can access blocks of sequential data. Of course, most file systems also provide random access, so streams do offer things like Seek, Position, Length etc - but not all implementations support such. It has no meaning to seek some streams, or get the length of an open socket.
A buffer has a specified size/length and is used to store data. The Stream on the other hand is used to read and write information from one place to another. For example FileStream is used to read and write to and from files.
The stream itself has a buffer which buffer when filled to its max size is flushed and the data in the stream is read or written.
I want to create a file using byte[], which one is best.
byte[] content=File.ReadAllBytes(#"C:\ServiceLog.txt");
FileStream stream = new FileStream(#"C:\ServiceLog1.txt", FileMode.Create, FileAccess.ReadWrite);
stream.Write(content, 0, content.Length);
stream.Close();
or
File.WriteAllBytes(#"C:\12.txt",content);
If you have a byte[], you might as well just use WriteAllBytes and let the wrapper method worry about the rest. The Stream approach is useful when you are (oddly enough) streaming the data, meaning: you might not know it all when you start writing. Since you do have the byte[], just us it. However, in the general case, note that byte[]-based APIs may have more impact on memory than Stream-based APIs, especially for large content.
All your bytes are already in memory, so as well use:
File.WriteAllBytes(#"C:\12.txt",content);
Stream methods are useful when you are dealing with very large files, and don't want to keep everything in memory.
A decompression API that I am using has the following API:
Decode(Stream inStream,Stream outStream)
I'd like to create a wrapper around this API, such that I can create my own Stream class which offers up the decoded data.
Stream decodedStream=new BlaDecodeStream(inStream);
So that I can than use this stream as a parameter to the XmlReader constructor in the same way one might use the System.IO.Compression.GZipStream. As far as I can tell, the only other option is set outStream stream to a MemoryStream or to a FileStream and go in two hops. The files I am dealing with are enormous, so neither of these options are particularly attractive.
Before I go reinventing the wheel, is there any prior art that I might be able to draw from, or something in the BCL I might have missed? The CircularStream implementation here would go some of the way to helping, but I'm really looking for something similar that would block (as opposed to over/underrun) when the Stream's internal buffer is 'empty' when reading from it and block when the internal buffer is full when writing to it.
In this way it could serve as parameter outStream and simultaneously (i.e. from another thread) could be read from by the XmlReader.
I asked about a blocking stream reader a while ago. I implemented one of the suggestions and it works fine.