如何从流中准确读取 n 个字节?
- 作者: 赞我JJ长5CM461
- 来源: 51数据库
- 2023-02-13
问题描述
这比我最初想象的要棘手一些.我正在尝试从流中读取 n 个字节.
This is a little more tricky than I first imagined. I'm trying to read n bytes from a stream.
MSDN 声称Read 不必返回 n 个字节,它只需要返回至少 1 个和最多 n 个字节,其中 0 个字节是到达流末尾的特殊情况.
The MSDN claims that Read does not have to return n bytes, it just must return at least 1 and up to n bytes, with 0 bytes being the special case of reaching the end of the stream.
通常,我使用类似的东西
Typically, I'm using something like
var buf = new byte[size]; var count = stream.Read (buf, 0, size); if (count != size) { buf = buf.Take (count).ToArray (); } yield return buf;
我希望正好是 size 字节,但根据规范 FileStream 也可以返回大量的 1 字节块.必须避免这种情况.
I'm hoping for exactly size bytes but by spec FileStream would be allowed to return a large number of 1-byte chunks as well. This must be avoided.
解决这个问题的一种方法是拥有 2 个缓冲区,一个用于读取,另一个用于收集块,直到我们获得请求的字节数.不过有点麻烦.
One way to solve this would be to have 2 buffers, one for reading and one for collecting the chunks until we got the requested number of bytes. That's a little cumbersome though.
我还查看了 BinaryReader 但它的规范也确实如此没有明确说明肯定会返回n个字节.
I also had a look at BinaryReader but its spec also does not clearly state that n bytes will be returned for sure.
澄清:当然,在流结束时,返回的字节数可能小于 size - 这不是问题.我只是在谈论不接收 n 个字节,即使它们在流中可用.
To clarify: Of course, upon the end of the stream the returned number of bytes may be less than size - that's not a problem. I'm only talking about not receiving n bytes even though they are available in the stream.
推荐答案
可读性更强的版本:
int offset = 0; while (offset < count) { int read = stream.Read(buffer, offset, count - offset); if (read == 0) throw new System.IO.EndOfStreamException(); offset += read; }
或者写成Stream类的扩展方法:
Or written as an extension method for the Stream class:
public static class StreamUtils { public static byte[] ReadExactly(this System.IO.Stream stream, int count) { byte[] buffer = new byte[count]; int offset = 0; while (offset < count) { int read = stream.Read(buffer, offset, count - offset); if (read == 0) throw new System.IO.EndOfStreamException(); offset += read; } System.Diagnostics.Debug.Assert(offset == count); return buffer; } }
- C#通过fleck实现wss协议的WebSocket多人Web实时聊天(附源码)
- 团队城市未满足要求:MSBuildTools12.0_x86_Path 存在
- 使用 MSBuild.exe 在发布模式下构建 C# 解决方案
- 当我发布 Web 应用程序时,AfterPublish 脚本不运行
- 构建时 T4 转换的产品仅在下一个构建中使用
- ASP.NET Core Application (.NET Framework) for Windows x64 only error in project.assets.json
- 新的 .csproj 格式 - 如何将整个目录指定为“链接文件"到子目录?
- 如何将条件编译符号(DefineConstants)传递给 msbuild
- MSBuild 支持 Visual Studio 2017 RTM 中的 T4 模板
- NuGet 包还原找不到包,没有源