悠悠楠杉
C怎么将二进制数据写入文件
在开发过程中,经常会遇到需要将非文本类型的数据(如图像、音频、序列化对象等)保存到磁盘的需求。这类数据通常以二进制形式存在,不能简单地用字符串方式处理。C# 提供了多种高效且安全的方式来将二进制数据写入文件,掌握这些方法对于构建稳定可靠的桌面或服务端应用至关重要。
为什么使用二进制写入?
与文本文件不同,二进制文件可以精确保存原始字节内容,避免编码转换带来的数据丢失。例如,当你需要保存一个加密后的数据块、网络传输的缓冲区,或者一个通过 MemoryStream 生成的图片时,必须确保每一个字节都原样写入目标文件。此时,使用二进制写入是唯一正确的方式。
使用 FileStream 直接写入字节数组
最基础也是最常用的方法是使用 System.IO.FileStream 类。它允许你以流的形式打开文件,并将字节数组直接写入磁盘。
csharp
byte[] data = { 0x48, 0x65, 0x6C, 0x6C, 0x6F }; // 示例:Hello 的 ASCII 码
using (FileStream fs = new FileStream("output.bin", FileMode.Create, FileAccess.Write))
{
fs.Write(data, 0, data.Length);
}
这段代码创建了一个名为 output.bin 的文件,并将字节数组写入其中。FileMode.Create 表示如果文件已存在则覆盖,FileAccess.Write 指定只写权限。using 语句确保流在操作完成后被正确释放,防止资源泄漏。
这种方法的优点是简单直接,适合已知完整字节数组的场景。但如果要连续写入不同类型的数据(如先写整数再写字符串),手动管理偏移和字节转换会变得繁琐。
使用 BinaryWriter 简化复杂数据写入
当需要写入结构化二进制数据时,BinaryWriter 是更优雅的选择。它封装了 FileStream,并提供了一系列强类型写入方法,如 Write(int)、Write(string)、Write(double) 等,自动完成类型到字节的转换。
csharp
using (FileStream fs = new FileStream("data.bin", FileMode.Create))
using (BinaryWriter writer = new BinaryWriter(fs))
{
writer.Write(12345); // 写入一个整数
writer.Write(3.14159); // 写入双精度浮点数
writer.Write("Hello World"); // 写入字符串(带长度前缀)
writer.Write(true); // 写入布尔值
}
BinaryWriter 会按照 .NET 的默认编码规则(如 UTF-8)处理字符串,并在写入字符串时自动添加长度信息,便于后续读取。这种方式特别适用于保存配置、序列化简单对象或构建自定义二进制协议。
需要注意的是,BinaryWriter 的读写必须配套使用 BinaryReader,否则无法正确解析带长度前缀的字符串或变长数据。
处理大文件或流式数据
对于大型二进制数据(如视频文件、数据库导出包),一次性加载到内存可能造成性能问题。此时应采用分块写入策略:
csharp
byte[] buffer = new byte[4096];
using (FileStream inputFile = File.OpenRead("source.dat"))
using (FileStream outputFile = File.Create("copy.dat"))
{
int bytesRead;
while ((bytesRead = inputFile.Read(buffer, 0, buffer.Length)) > 0)
{
outputFile.Write(buffer, 0, bytesRead);
}
}
这种方式逐块读取源文件并写入目标文件,内存占用恒定,适合处理 GB 级别的文件复制或下载保存。
注意事项与最佳实践
- 始终使用
using语句确保流被及时关闭。 - 写入前检查目录是否存在,避免因路径无效导致异常。
- 对于跨平台应用,注意字节序(Endianness)问题,必要时手动反转字节。
- 敏感数据写入后可考虑调用
File.SetAttributes设置隐藏属性,或使用加密流增强安全性。
掌握这些技巧后,无论是保存用户上传的文件、缓存计算结果,还是实现自定义文件格式,你都能游刃有余地在 C# 中完成二进制数据的持久化操作。

