多线程写入二进制文件后读取数据异常,加锁未解决的问题求助
多线程写入二进制文件后读取数据异常,加锁未解决的问题求助
看起来你遇到的问题确实很棘手——明明写入前和写入过程中数据都正常,单文件写入也没问题,多线程共享写入就出问题,加了锁还没解决。我来帮你梳理下可能的原因和对应的解决思路:
可能的问题点及解决方案
1. 锁的范围或对象使用不当
你用了静态的locker对象,这本身是合理的,但要确保所有写入操作都严格绑定同一个锁对象,而且锁要完整包裹住从文件打开到关闭的全流程。如果之前你的锁只覆盖了数据处理逻辑,没锁文件IO环节,那多线程还是可能同时操作文件流,导致数据错乱。正确的写法应该是:
private static object locker = new object(); private string targetFilePath = "your_target_file.bin"; public void Serialize(byte[] dataToWrite) { lock(locker) { // 将打开流、写入数据、关闭流的全流程都放在锁内 using (var fileStream = new FileStream(targetFilePath, FileMode.Append, FileAccess.Write, FileShare.None)) using (var writer = new BinaryWriter(fileStream)) { writer.Write(dataToWrite); } } }
2. 全局复用FileStream/BinaryWriter导致状态混乱
如果你的代码里是全局共享同一个FileStream或BinaryWriter对象,哪怕加了锁,也可能因为流的位置指针、缓冲区状态被多线程干扰而出错。这种情况下,每次写入都应该重新创建流和写入器,让锁保护整个创建-写入-销毁的完整周期,避免跨线程的状态污染。
3. FileShare参数设置不合理
如果打开文件时用了FileShare.ReadWrite这类宽松的共享权限,即使加了代码层面的锁,其他线程或进程仍可能干扰文件内容。建议打开文件时指定FileShare.None,确保同一时间只有一个写入操作能访问目标文件。
4. 锁对象被意外篡改
虽然你用了静态locker对象,但要排查代码中有没有地方意外重新赋值了这个对象(比如在某个方法里重新创建了locker)。如果不同线程使用的是不同的锁对象,那加锁等于无效。
额外排查建议
- 可以在写入时,把每次写入的数组开头数字、线程ID、写入时间记录到日志,读取时对比日志,排查是不是有写入操作被覆盖或数据拼接错误。
- 检查读取代码的逻辑,比如你提到的313变成28164,计算下:313的十六进制是
0x139,28164是0x6E04,看起来像是字节序反转,但单线程写入没问题的话这个概率较低,不过可以确认读取时的整数解析方式是否和写入匹配。
备注:内容来源于stack exchange,提问作者dragondangun
相关产品推荐
相关产品推荐

