了解克隆流的不同方法,以及使用哪种方法

时间:2011-09-29 17:25:55

标签: .net stream

复制文件流时,我遇到了两个例子:

这一个,

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

和这一个:

    '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

我的理解是第一个将一个流直接复制到另一个流,第二个通过字节数组复制。两者都工作并实现相同的目标。我相信第一个会更快,但第二个看起来更简单,更容易维护等。

我无法看到你在第一个中设置编码的位置。为什么你需要在一个中完成,而不是另一个?

此外,对每个片段的专业版和内容的客观评论也很有用。 THX

1 个答案:

答案 0 :(得分:2)

第二个使用任意二进制数据 - 它将数据视为UTF-8编码的文本数据,然后对其进行重新编码 - 这是非常糟糕的主意< / em>除非您确实知道它的UTF-8编码文本。

第二种形式也使用字节数组,一次只使用一个缓冲区。

但是,您在第一个版本中遇到了错误:当bytesRead非零时,您将继续前进,但启动为0

你可能想要:

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

在C#中我使用:

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

但我不知道你是否可以在VB中进行类似的复合赋值。

其他一些选择:

  • 您可以使用File.ReadAllBytes将整个文件作为字节数组读取,但如果它是一个大文件,显然会浪费内存。这是第二个代码的一种安全版本。
  • 如果您正在使用.NET,则可以使用Stream.CopyTo(Stream)。如果没有,您可以自己编写相同的代码作为扩展方法,以便从其他项目中重复使用。