开发者

Understanding different methods of cloning a stream, and which situation to use which in

When copying a file stream, I've come开发者_JS百科 across two examples:

This one,

Using requestStream as IO.Stream = state.Request.EndGetRequestStream(ar)
    ' Copy the file contents to the request stream.
    Const bufferLength As Integer = 2048
    Dim buffer(bufferLength - 1) As Byte
    Dim count As Integer = 0
    Dim readBytes As Integer = 0
    Using stream As IO.FileStream = IO.File.OpenRead(state.FileName)
        While readBytes <> 0
            readBytes = stream.Read(buffer, 0, bufferLength)
            requestStream.Write(buffer, 0, readBytes)
            count += readBytes
        End While
    End Using
End Using

and this one:

    'Copy the contents of the file to the request stream.
    Dim fileContents As Byte()
    Using fileStream As New IO.StreamReader(state.FileName)
        fileContents = Encoding.UTF8.GetBytes(fileStream.ReadToEnd())
    End Using

    Using requestStream As IO.Stream = state.Request.EndGetRequestStream(ar)
        requestStream.Write(fileContents, 0, fileContents.Length)
    End Using

My understanding is that the first one copies one stream directly to another, the second copies via a byte array. Both work and achieve the same thing. I believe the first one would be quicker, but the second one looks a lot simpler and easier to maintain etc.

I can't see where you set the encoding in the first one though. Why would you need to do it in one, but not the other?

Also, objective comments on the pro's and con's of each snippet would be useful. Thx


The second one will not work with arbitrary binary data - it treats the data as UTF-8-encoded text data, then re-encodes it - this is a very bad idea unless you actually know it's UTF-8-encoded text.

The second form uses a byte array as well, just one buffer at a time.

However, you've got a bug in the first version: you're going to keep going while bytesRead is non-zero, but it starts as 0.

You might want:

Using stream As IO.FileStream = IO.File.OpenRead(state.FileName)
    readBytes = stream.Read(buffer, 0, bufferLength)
    While readBytes <> 0
        requestStream.Write(buffer, 0, readBytes)
        count += readBytes
        readBytes = stream.Read(buffer, 0, bufferLength)
    End While
End Using

In C# I'd use:

int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, bufferLength)) > 0)
{
    requestStream.Write(buffer, 0, readBytes);
    count += readBytes;
}

but I don't know whether you can do a compound assignment like that in VB.

Some other options:

  • You can use File.ReadAllBytes to read a whole file as a byte array, although obviously that will waste memory if it's a large file. This is a sort of safe version of your second code.
  • You can use Stream.CopyTo(Stream) if you're using .NET 4. If not, you could potentially write the same code yourself as an extension method to be reused from other projects.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜