MemoryStream.WriteTo (stream destinationStream) compared to Stream.CopyTo (stream destinationStream)

Which one is better: MemoryStream.WriteTo(Stream destinationStream) or Stream.CopyTo(Stream destinationStream) ??

I am talking about comparing these two methods without Buffer, as I do like this:

 Stream str = File.Open("SomeFile.file"); MemoryStream mstr = new MemoryStream(File.ReadAllBytes("SomeFile.file")); using(var Ms = File.Create("NewFile.file", 8 * 1024)) { str.CopyTo(Ms) or mstr.WriteTo(Ms);// Which one will be better?? } 

Update

Here is what I want to do:

  • Open File [Say "X" File Type]
  • Content parsing
  • From here I get Bunch of new Streams [3 ~ 4 Files]
  • Single stream analysis
  • Extract thousands of files [The Stream is an image file]
  • Save other streams in files
  • Editing all files
  • Create a new file of type "X".

I wrote every bit of code that really works correctly.

But now I am optimizing the code to make it most efficient.

+7
source share
6 answers

It is a historical disaster that there are two ways to do the same. MemoryStream always had a WriteTo () method, Stream didn't get a CopyTo () method before .NET 4.

The version of MemoryStream.WriteTo () looks like this:

 public virtual void WriteTo(Stream stream) { // Exception throwing code elided... stream.Write(this._buffer, this._origin, this._length - this._origin); } 

Implementation of Stream.CopyTo ():

 private void InternalCopyTo(Stream destination, int bufferSize) { int num; byte[] buffer = new byte[bufferSize]; while ((num = this.Read(buffer, 0, buffer.Length)) != 0) { destination.Write(buffer, 0, num); } } 

Stream.CopyTo () is more universal, it works for any stream. And it helps programmers who jump over copying data, say, from NetworkStream. Forgetting to pay attention to the return value from Read () was a very common mistake. But he, of course, copies bytes twice and allocates this temporary buffer , a MemoryStream does not need it, since it can write directly from its own buffer. Therefore, you still prefer WriteTo (). A remark about the difference is not very likely.

+15
source

MemoryStream.WriteTo : writes the entire contents of this memory stream to another stream.

Stream.CopyTo : reads bytes from the current stream and writes them to the destination stream. Copying starts at the current position of the current stream. You will need to go back to 0 to copy the entire source stream.

So, I think MemoryStream.WriteTo is the best option for this situation.

+6
source

If you use Stream.CopyTo , you do not need to read all the bytes in memory to start with. But:

  • This code will be simpler if you just used File.Copy
  • If you are going to load all the data into memory, you can simply use:

     byte[] data = File.ReadAllBytes("input"); File.WriteAllBytes("output", data); 
  • You must have a using statement for input as well as an output stream

If you really need processing, so you cannot use File.Copy , using Stream.CopyTo will work with large files than loading everything into memory. You may not need this, or you may need to load the entire file into memory for other reasons.

If you have a MemoryStream , I would probably use MemoryStream.WriteTo and not Stream.CopyTo , but it probably won't make much difference what you use, except that you need to make sure that you are at the beginning stream when using CopyTo .

+4
source

I think the Hans Passant requirement for an error in MemoryStream.WriteTo () is incorrect; it does not "ignore the return value of Write ()". Stream.Write () returns void, which implies that all bytes of the count are written, which implies that Stream.Write () will block as needed to complete the operation, for example, NetworkStream, or discard if it ultimately fails .

Is this really different than write () in? nix and its many emulations in libc, etc., which can return a "short record". I suspect that Hans came to the conclusion that Stream.Write () followed this, which I expected, but apparently does not.

It can be assumed that Stream.Write () can perform a “short record” without returning any indication of this, requiring the caller to check whether the Position Stream property has really been advanced in the account. This would be a very error prone API, and I doubt that it does, but I have not tested it completely. (Testing would be a little more complicated: I think you need to connect a TCP NetworkStream with a reader on the other end that is locked forever, and write enough to fill the wire buffers. Or something like that ...)

Comments for Stream.Write () are not entirely clear:

Summary: When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position in this stream by the number of bytes written. Parameters: buffer: An array of bytes. This method copies the number of bytes from the buffer into the current stream.

Compare this to the Linux work page for writing (2):

write () writes to count the bytes from the buffer specified in buf to the file specified by the file descriptor fd.

Pay attention to the "do". This proposal is followed by an explanation of some of the conditions under which a “short record” may occur, which makes it very obvious that this can happen.

This is really a critical issue: we need to know how Stream.Write () behaves, without a doubt.

+1
source

The CopyTo method creates a buffer, fills it with data from the source stream, and then calls the Write method, passing the created buffer as a parameter. WriteTo uses the internal memoryStream buffer for writing. That is the difference. Which is better - you decide which method you prefer.

0
source

Creating a MemoryStream from an HttpInputStream in Vb.Net:

 Dim filename As String = MyFile.PostedFile.FileName Dim fileData As Byte() = Nothing Using binaryReader = New BinaryReader(MyFile.PostedFile.InputStream) binaryReader.BaseStream.Position = 0 fileData = binaryReader.ReadBytes(MyFile.PostedFile.ContentLength) End Using Dim memoryStream As MemoryStream = New MemoryStream(fileData) 
0
source

All Articles