#%#$#%@%@%$#%$#%#%#$%@_240aa2c++ec4b29c56f3bee520a8dcee7e中的binaryreader和binarywriter用于以二进制形式精确读写数据流,1. 它们直接操作底层流(如filestream),支持基本数据类型(int、string、bool等)的读写;2. 使用using语句确保资源正确释放;3. 写入和读取顺序必须严格一致,否则会导致数据错乱或异常;4. 相比streamreader/writer,binaryreader/writer保留数据的原始字节表示,适用于非文本数据(如数值、图片、音频);5. 处理自定义类型时需手动序列化,先写字段长度再写数据,并注意版本控制;6. 跨平台使用时需应对字节序(endianness)差异,建议统一使用小端序或进行转换;7. 字符串应明确使用utf-8编码并先写入长度;8. 避免使用已过时且不安全的binaryformatter,推荐手动序列化或使用protobuf等现代序列化库;9. 与c/c++交互时需确保数据结构对齐和字节顺序一致;10. 最佳实践是定义清晰的二进制协议规范,确保跨系统兼容性。

C#中的
BinaryReader
BinaryWriter
在使用C#的
BinaryReader
BinaryWriter
FileStream
MemoryStream
一个典型的写入和读取流程看起来是这样的:
using System;
using System. స్థాపించు;
using System.IO;
public class BinaryDataExample
{
    public static void WriteAndReadData(string filePath)
    {
        // 写入数据
        try
        {
            using (FileStream fs = new FileStream(filePath, FileMode.Create))
            {
                using (BinaryWriter writer = new BinaryWriter(fs))
                {
                    writer.Write(12345); // int
                    writer.Write("Hello Binary!"); // string
                    writer.Write(true); // bool
                    writer.Write(3.14159f); // float
                    writer.Write(123.456789012345); // double
                    writer.Write((byte)255); // byte
                    writer.Write(new byte[] { 0x01, 0x02, 0x03, 0x04 }); // byte array
                    Console.WriteLine($"数据已写入到 {filePath}");
                }
            }
        }
        catch (IOException ex)
        {
            Console.WriteLine($"写入文件时发生错误: {ex.Message}");
        }
        // 读取数据
        try
        {
            using (FileStream fs = new FileStream(filePath, FileMode.Open))
            {
                using (BinaryReader reader = new BinaryReader(fs))
                {
                    int intValue = reader.ReadInt32();
                    string stringValue = reader.ReadString();
                    bool boolValue = reader.ReadBoolean();
                    float floatValue = reader.ReadSingle();
                    double doubleValue = reader.ReadDouble();
                    byte byteValue = reader.ReadByte();
                    byte[] byteArray = reader.ReadBytes(4); // 读取之前写入的4个字节
                    Console.WriteLine("\n读取到的数据:");
                    Console.WriteLine($"Int: {intValue}");
                    Console.WriteLine($"String: {stringValue}");
                    Console.WriteLine($"Bool: {boolValue}");
                    Console.WriteLine($"Float: {floatValue}");
                    Console.WriteLine($"Double: {doubleValue}");
                    Console.WriteLine($"Byte: {byteValue}");
                    Console.WriteLine($"Byte Array: {BitConverter.ToString(byteArray)}");
                }
            }
        }
        catch (IOException ex)
        {
            Console.WriteLine($"读取文件时发生错误: {ex.Message}");
        }
        catch (EndOfStreamException)
        {
            Console.WriteLine("文件读取完毕,但可能未按预期读取所有数据。请检查写入和读取顺序是否一致。");
        }
    }
    public static void Main(string[] args)
    {
        string fileName = "mydata.bin";
        WriteAndReadData(fileName);
        // 清理文件,实际应用中可能不需要
        // File.Delete(fileName);
    }
}这里有几个我特别看重的地方:首先是
using
EndOfStreamException
这其实是一个关于“数据本质”的问题。
StreamReader
StreamWriter
StreamWriter.WriteLine("123")0x31 0x32 0x33
但当我们谈论二进制数据时,我们通常指的是那些不直接代表字符,而是代表数值、结构体、图片像素、音频样本等原始字节信息。比如,一个整数
12345
0x39 0x30 0x00 0x00
StreamWriter
BinaryReader
BinaryWriter
BinaryWriter.Write(12345)
12345
BinaryReader.ReadInt32()
Int32
BinaryReader/Writer
处理复杂数据结构或自定义类型时,
BinaryReader
BinaryWriter
Person
我通常会采取以下几种策略或注意点:
手动序列化与反序列化: 这是最直接的方式。为你的自定义类定义
WriteTo
ReadFrom
Serialize
Deserialize
WriteTo
BinaryWriter
Write
ReadFrom
BinaryReader
public class UserProfile
{
    public int Id { get; set; }
    public string Username { get; set; }
    public DateTime LastLogin { get; set; }
    public byte[] AvatarData { get; set; } // 假设是图片数据
    public void Write(BinaryWriter writer)
    {
        writer.Write(Id);
        writer.Write(Username);
        writer.Write(LastLogin.ToBinary()); // DateTime需要特殊处理,ToBinary()是好选择
        // 写入字节数组前,通常需要先写入数组长度,以便读取时知道要读多少
        writer.Write(AvatarData.Length); 
        writer.Write(AvatarData);
    }
    public void Read(BinaryReader reader)
    {
        Id = reader.ReadInt32();
        Username = reader.ReadString();
        LastLogin = DateTime.FromBinary(reader.ReadInt64());
        int avatarLength = reader.ReadInt32();
        AvatarData = reader.ReadBytes(avatarLength);
    }
}这里最关键的就是顺序和长度。写入时你先写了ID,那么读取时第一个就得读ID。对于变长数据(比如字符串或字节数组),你必须在写入数据本身之前,先写入它的长度,这样读取时才知道要读多少字节。
版本控制: 你的数据结构可能会随着软件迭代而改变。比如,你可能在
UserProfile
// 写入时
writer.Write(1); // 版本号
writer.Write(Id);
writer.Write(Username);
if (version >= 2) // 假设版本2开始有Email
{
    writer.Write(Email);
}
// 读取时
int version = reader.ReadInt32();
Id = reader.ReadInt32();
Username = reader.ReadString();
if (version >= 2)
{
    Email = reader.ReadString();
}
// else: 如果是老版本文件,Email字段保持默认值或空这种方式虽然增加了代码的复杂性,但在实际应用中几乎是不可避免的。
避免BinaryFormatter
[Serializable]
BinaryFormatter
BinaryReader/Writer
BinaryFormatter
在跨平台或不同系统间使用
BinaryReader
BinaryWriter
字节序(Endianness): 这是最常见也是最令人头疼的问题。字节序指的是多字节数据类型(如
int
float
double
BinaryReader
BinaryWriter
int
BinaryReader
int
int
0x12345678
78 56 34 12
12 34 56 78
BitConverter.IsLittleEndian
Array.Reverse
IPAddress.HostToNetworkOrder
数据类型大小和表示: 尽管C#的基本数据类型(
int
long
int
int
字符串编码:
BinaryWriter.Write(string)
BinaryReader.ReadString()
// 写入时
byte[] stringBytes = System.Text.Encoding.UTF8.GetBytes("跨平台字符串");
writer.Write(stringBytes.Length); // 写入长度
writer.Write(stringBytes);       // 写入字节
// 读取时
int length = reader.ReadInt32();
byte[] readBytes = reader.ReadBytes(length);
string readString = System.Text.Encoding.UTF8.GetString(readBytes);数据结构对齐: 这个问题在C/C++等语言中更常见,它们为了性能可能会对结构体成员进行内存对齐,导致结构体实际占用空间大于各成员大小之和。虽然C#的
BinaryReader/Writer
解决这些挑战,通常需要你和目标系统之间定义一个明确的二进制协议或数据格式规范。这个规范会详细说明每个数据字段的类型、大小、字节序、字符串编码方式等,然后两端都严格遵循这个规范进行读写,并在必要时进行字节序转换。这就像制定一个国际通用的语言,确保大家都能理解彼此。
以上就是C#的BinaryReader和BinaryWriter如何读写二进制数据?的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号