C#读写二进制文件 C#如何操作二进制数据流

来源:这里教程网 时间:2026-02-21 17:41:51 作者:

BinaryReader
BinaryWriter
读写结构化二进制数据最稳妥

这两个类专为 .NET 的二进制序列化设计,自动处理字节序、类型长度和基础编码,比直接操作

Stream
更少出错。适用于保存/加载自定义结构体、数值数组、字符串(需注意编码)等。

常见错误:用

BinaryWriter.Write(string)
写入后,用
BinaryReader.ReadString()
读取失败——因为后者依赖前缀长度(UTF-8 编码的 7 位变长整数),若文件非它所写,会抛
EndOfStreamException
或乱码。

写字符串时,如需兼容性更强,改用
Write(byte[])
+
Encoding.UTF8.GetBytes()
读数值类型(
int
double
等)完全安全,它们按小端序固定长度写入
不要跨平台共享
BinaryReader
写出的文件——.NET 不保证其他语言能解析其字符串格式或类型标识

直接用
Stream.Read
/
Stream.Write
控制每个字节

当你需要精确控制布局(比如对接 C/C++ 结构体、网络协议头、图像 raw 数据),必须绕过高层封装,直接操作字节数组。

典型场景:读取 BMP 文件头(14 字节固定结构)、拼接加密后的字节块、解析自定义二进制协议包。

务必检查返回值:
Read()
可能只读到部分字节,需循环直到填满缓冲区或遇到 EOF
写入前确认
Stream.CanWrite
且已定位到正确位置(
Position
可写)
使用
MemoryStream
做中间缓存时,记得调用
ToArray()
获取真实字节,而非
GetBuffer()
(后者可能含未使用填充)

Span<byte></byte>
+
BinaryPrimitives
是高性能二进制解析新方案

.NET Core 2.1+ 引入了零分配的二进制解析方式,适合高频、大数据量场景(如日志解析、实时传感器数据流)。

它不依赖流对象,直接在内存切片上解析整数、浮点数,避免了

BinaryReader
的内部缓冲和装箱开销。

读取小端整数:
BinaryPrimitives.ReadInt32LittleEndian(data)
data
Span<byte></byte>
写入需手动复制:
BinaryPrimitives.WriteInt32LittleEndian(buffer, value)
不处理字符串、变长字段,所有偏移和长度都得自己算清楚——错一位就全盘错解

文件打开模式和编码陷阱必须显式指定

二进制操作最常被忽略的是

FileStream
构造参数。默认
FileMode.Open
+
FileAccess.Read
只读,想写必须显式设
FileAccess.ReadWrite
;追加写要用
FileMode.Append
并确保光标在末尾。

另一个坑是文本编码混入:哪怕你只读字节,如果用

StreamReader
打开二进制文件,它会尝试按 UTF-8 解码,遇到非法字节直接抛异常。

永远用
new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: true)
显式控制行为
避免把
byte[]
误传给
Encoding.GetString()
处理非文本数据(比如图片像素)
调试时用
File.ReadAllBytes()
快速看前几十字节十六进制,比盲目猜更可靠

二进制操作的核心不是“怎么写”,而是“谁定义了格式”。哪怕代码全对,只要和协议文档或 C 结构体对不上字段顺序、对齐、符号位,数据就不可用。建议先用十六进制编辑器对照验证几组手工构造的数据。

相关推荐