2011-09-29 71 views
0

当复制一个文件流,我遇到了两个例子:了解不同的方法,并且情况下使用这

这一个,

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 

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

我看不到你在第一个中设置编码的位置。你为什么需要一个人做,而不是另一个呢?

此外,对每个片段的pro和con的客观评论将是有用的。 THX

回答

2

第二个会与任意的二进制数据的工作 - 它会将数据为UTF-8编码的文本数据,然后重新编码它 - 这是一个非常糟糕的主意除非你真正知道它的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 4,则可以使用Stream.CopyTo(Stream)。如果不是,则可以自己编写相同的代码作为扩展方法,以便从其他项目中重用。
+1

你会推荐什么样的缓冲区大小? (如果你不知道使用的典型文件大小) – Magnus

+1

@Magnus:我通常使用8或16K。不要超过80K,否则缓冲区将会在大对象堆上结束。 –

+0

@JonSkeet谢谢你,很好的评论和回答,我会用你的例子,但有一个while循环,因为我有一个无理的厌恶做循环。 –

相关问题