It really depends on whether or not you can trust s.Length
.
(这真的取决于你是否可以信任s.Length
。)
For many streams, you just don't know how much data there will be. (对于许多流,您只是不知道将有多少数据。)
In such cases - and before .NET 4 - I'd use code like this: (在这种情况下 - 在.NET 4之前 - 我会使用这样的代码:)
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16*1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
With .NET 4 and above, I'd use Stream.CopyTo
, which is basically equivalent to the loop in my code - create the MemoryStream
, call stream.CopyTo(ms)
and then return ms.ToArray()
.
(使用.NET 4及更高版本,我将使用Stream.CopyTo
,它基本上等同于我的代码中的循环 - 创建MemoryStream
,调用stream.CopyTo(ms)
然后返回ms.ToArray()
。)
Job done. (任务完成。)
I should perhaps explain why my answer is longer than the others.
(我或许应该解释为什么我的回答比其他人长。)
Stream.Read
doesn't guarantee that it will read everything it's asked for. (Stream.Read
并不保证它会读取它所要求的所有内容。)
If you're reading from a network stream, for example, it may read one packet's worth and then return, even if there will be more data soon. (例如,如果您正在从网络流中读取数据,它可能会读取一个数据包的值,然后返回,即使很快会有更多数据。)
BinaryReader.Read
will keep going until the end of the stream or your specified size, but you still have to know the size to start with. (BinaryReader.Read
将继续运行直到流的末尾或您指定的大小,但您仍然必须知道要开始的大小。)
The above method will keep reading (and copying into a MemoryStream
) until it runs out of data.
(上面的方法将继续读取(并复制到MemoryStream
),直到它用完数据。)
It then asks the MemoryStream
to return a copy of the data in an array. (然后它要求MemoryStream
返回数组中的数据副本。)
If you know the size to start with - or think you know the size, without being sure - you can construct the MemoryStream
to be that size to start with. (如果您知道要开始的大小 - 或者认为您知道大小,而不确定 - 您可以将MemoryStream
构造为该大小。)
Likewise you can put a check at the end, and if the length of the stream is the same size as the buffer (returned by MemoryStream.GetBuffer
) then you can just return the buffer. (同样,您可以在结尾处进行检查,如果流的长度与缓冲区的大小相同(由MemoryStream.GetBuffer
返回),那么您只需返回缓冲区即可。)
So the above code isn't quite optimised, but will at least be correct. (所以上面的代码并没有得到很好的优化,但至少是正确的。)
It doesn't assume any responsibility for closing the stream - the caller should do that. (关闭流不承担任何责任 - 调用者应该这样做。)
See this article for more info (and an alternative implementation).
(有关更多信息(以及替代实现),请参阅此文章 。)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…