C#中将结构体数据写入二进制文件的实现求助
嘿,我看你现在在尝试把自定义结构体写入二进制文件时遇到了瓶颈——你的代码里BinaryWriter.Write()还没填具体内容对吧?别担心,这其实是个很常见的场景,咱们有几种靠谱的实现方式,我给你拆解清楚。
首先,你的TSensor是自定义值类型,BinaryWriter默认没有直接序列化整个结构体的方法,所以我们可以从以下几种思路入手:
方法1:逐个写入结构体成员(最直观、可控)
这种方法适合你需要严格控制二进制文件格式的场景,直接把结构体的每个字段依次写入文件:
public struct TSensor { public byte b1; public int i1; public float f1; } class Program { const string fileName = "AppSettings.bin"; static void Main() { // 先创建并填充结构体实例 TSensor sensorData = new TSensor { b1 = 0x01, i1 = 123, f1 = 45.67f }; using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create))) { // 按顺序写入每个成员 writer.Write(sensorData.b1); writer.Write(sensorData.i1); writer.Write(sensorData.f1); } } }
注意:后续读取文件时,必须严格按照写入的顺序读取对应的类型,否则会出现数据错乱。
方法2:使用BinaryFormatter序列化(自动化程度高)
如果你不需要手动控制二进制格式,只想快速实现序列化,可以用BinaryFormatter,不过要记得给结构体加上[Serializable]特性:
using System.Runtime.Serialization.Formatters.Binary; [Serializable] public struct TSensor { public byte b1; public int i1; public float f1; } class Program { const string fileName = "AppSettings.bin"; static void Main() { TSensor sensorData = new TSensor { b1 = 0x01, i1 = 123, f1 = 45.67f }; using (FileStream stream = File.Open(fileName, FileMode.Create)) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, sensorData); } } }
注意:在.NET Core/.NET 5+版本中,你需要先安装System.Runtime.Serialization.Formatters NuGet包才能使用BinaryFormatter;另外,这种方式生成的二进制文件会包含额外的元数据,体积会比手动写入大一点。
方法3:直接操作内存(高性能场景)
如果你的场景对性能要求很高,可以用MemoryMarshal把结构体直接转为Span<byte>,再写入文件,这种方式几乎没有额外开销:
using System.Runtime.InteropServices; public struct TSensor { public byte b1; public int i1; public float f1; } class Program { const string fileName = "AppSettings.bin"; static void Main() { TSensor sensorData = new TSensor { b1 = 0x01, i1 = 123, f1 = 45.67f }; using (FileStream stream = File.Open(fileName, FileMode.Create)) { // 将结构体直接转为字节Span Span<byte> sensorBytes = MemoryMarshal.AsBytes<TSensor>(ref sensorData); stream.Write(sensorBytes); } } }
注意:这种方式依赖结构体的内存布局,如果结构体包含引用类型或者需要跨平台兼容,最好加上[StructLayout(LayoutKind.Sequential)]特性来固定内存顺序,同时要注意字节序(大端/小端)的问题。
你可以根据自己的需求选择合适的方法,比如需要精准控制格式选方法1,快速实现选方法2,追求性能选方法3。
内容的提问来源于stack exchange,提问作者sidelaunch

