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.
Related
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.
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.
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.
Why do we need Reader/Writer Streams while Using TCPListner in C# networking?
example :
TcpClient client = server.AcceptTcpClient();
client.ReceiveTimeout = 75000;
Stream s = client.GetStream();
StreamReader reader = new StreamReader(s);
StreamWriter writer = new StreamWriter(s);
writer.AutoFlush = true;
You only need StreamReader/StreamWriter if you want to deal with text instead of binary data.
Sockets deal with binary data naturally, which is why TcpClient exposes a Stream. Stream is a binary abstraction, hence its Read/Write methods deal in byte arrays. TextReader/TextWriter (from which StreamReader/StreamWriter are derived) deal with text - their methods deal with strings and char arrays.
StreamReader/StreamWriter basically wrap a stream and do the conversion (via an Encoding) between text and binary data for you.
The TcpListener is designed to use streams for a couple of reasons.
First, it makes the API consistent with other, mid-high level (compared to using raw sockets) APIs in the BCL. For example, the standard way of handling File IO is to use Streams.
Second, streams provide a huge advantage for reading and writing to TCP channels. True, when you are working on very simple cases, they make life slightly, but just slightly, more difficult. However, when you start looking at more complex scenarios, they make everything much simpler.
For example, if the Tcp API didn't use streams, it would be much more difficult to do things like compress traffic across the connection (just pass the writer+reader through a GZipStream or similar), or much more difficult to encrypt all of your communication across the wire. Streams provide huge amounts of opportunity to easily extend your algorithm to handle situations that may arise in the future.
You don't need them. You can use raw sockets if you don't like the Tcp wrapper classes. Take a look at System.Net.Sockets.
I receive the follow exception:
System.NotSupportedException : This stream does not support seek operations.
at System.Net.Sockets.NetworkStream.Seek(Int64 offset, SeekOrigin origin)
at System.IO.BufferedStream.FlushRead()
at System.IO.BufferedStream.WriteByte(Byte value)
The follow link show that this is a known problem for microsoft.
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=273186
This stacktrace show 2 things:
The System.IO.BufferedStream do some absurd pointer move operation. A BufferedStream should buffer the underlying stream and not more. The quality of buffer will be bad if there are such seek operation.
It will never work stable with a stream that not support Seek.
Are there any alternatives?
Does I need a buffer together with a NetworkStream in C# or is this already buffered.
Edit: I want simply reduce the number of read/write calls to the underlying socket stream.
The NetworkStream is already buffered. All data that is received is kept in a buffer waiting for you to read it. Calls to read will either be very fast, or will block waiting for data to be received from the other peer on the network, a BufferedStream will not help in either case.
If you are concerned about the blocking then you can look at switching the underlying socket to non-blocking mode.
The solution is to use two independent BufferedStreams, one for receiving and one for sending. And don't forget to flush the sending BufferedStream appropriately.
Since even in 2018 it seems hard to get a satisfying answer to this question, for the sake of humanity, here are my two cents:
The NetworkStream is buffered on the OS side. However, that does not mean there are no reasons to buffer on the .net side. TCP behaves well on Write-Read (repeat), but stalls on Write-Write-Read due to delayed ack, etc, etc.
If you, like me, have a bunch of sub-par protocol code to take into the twentyfirst century, you want to buffer.
Alternatively, if you stick to the above, you could also buffer only reads/rcvs or only writes/sends, and use the NetworkStream directly for the other side, depending on how broken what code is. You just have to be consistent!
What BufferedStream docs fail to make abundantly clear is that you should only switch reading and writing if your stream is seekable. This is because it buffers reads and writes in the same buffer. BufferedStream simply does not work well for NetworkStream.
As Marc pointed out, the cause of this lameness is the conflation of two streams into one NetworkStream which is not one of .net's greatest design decisions.
A BufferedStream simply acts to reduce the number of read/write calls to the underlying stream (which may be IO/hardware bound). It cannot provide seek capability (and indeed, buffering and seeking are in many ways contrary to eachother).
Why do you need to seek? Perhaps copy the stream to something seekable first - a MemoryStream or a FileStream - then do your actual work from that second, seekable stream.
Do you have a specific purpose in mind? I may be able to suggest more appropriate options with more details...
In particular: note that NetworkStream is a curiosity - with most streams, read/write relate to the same physical stream; however, a NetworkStream actually represents two completely independent pipes; read and write are completely unrelated. Likewise, you can't seek in bytes that have already zipped past you... you can skip data, but that is better done by doing a few Read opdrations and discarding the data.