.NET Framework写入GeoJSON文件损坏的原因及代码解决办法
问题描述
每年会多次遇到JSON或XML文件损坏的情况,推测是数据写入时内存缓冲区出现问题。程序会批量写入多个GeoJSON文件,这类文件通常一次性写入后不再修改,但出现了文件写入中途插入Windows日志、字节数据等导致损坏的罕见偶发现象。使用GeoJson.net和Newtonsoft.Json编写的VB.NET代码如下:
Dim line As New Feature.Feature(geometry, propDict, CStr(shape.Index)) Dim serializedData As String = JsonConvert.SerializeObject(line) Using outputFile As New IO.StreamWriter(pathName, True) outputFile.WriteLine(serializedData) End Using
请问该问题产生的原因是什么,在.NET Framework(VB.NET或C#)中是否有办法通过代码避免?
问题原因与解决方案
问题原因
- 并发写入冲突:代码使用了StreamWriter的追加模式(第二个参数为
True),若程序存在多线程并发写入同一文件,或有其他进程(如系统日志进程、杀毒软件)访问该文件,StreamWriter本身并非线程安全,会导致不同来源的内容混杂写入,出现插入无关数据的情况。 - 文件路径重复:批量处理时若逻辑有误,可能导致多个写入任务指向同一文件路径,引发多进程/线程的写入冲突。
- 磁盘缓存未及时落盘:系统磁盘缓存机制可能导致数据未立即写入磁盘,若此时程序异常终止或系统波动,可能造成文件内容不完整,但这种情况极少出现混杂其他内容的现象。
代码层面的解决办法
- 强制独占文件访问:使用
FileStream指定独占访问权限,避免其他进程/线程干扰写入,一旦有其他访问会直接抛出异常,而非破坏文件内容:
Using fs As New IO.FileStream(pathName, IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.None) Using outputFile As New IO.StreamWriter(fs) outputFile.WriteLine(serializedData) End Using End Using
- 避免并发写入同一文件:批量处理时确保每个文件的写入操作串行执行,或通过锁机制控制同一文件的写入访问:
// C# 锁机制示例 private static readonly object _fileLock = new object(); lock (_fileLock) { using (var fs = new FileStream(pathName, FileMode.Append, FileAccess.Write, FileShare.None)) using (var writer = new StreamWriter(fs)) { writer.WriteLine(serializedData); } }
- 改用创建模式而非追加:如果文件是一次性写入后不再修改,优先使用
FileMode.Create创建新文件,从根源避免多次写入的冲突:
Using outputFile As New IO.StreamWriter(pathName, False) ' 第二个参数为False表示覆盖创建新文件 outputFile.WriteLine(serializedData) End Using
- 强制刷新磁盘写入:显式调用刷新方法,确保数据立即写入磁盘,避免缓存导致的异常:
Using fs As New IO.FileStream(pathName, IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.None) Using outputFile As New IO.StreamWriter(fs) outputFile.WriteLine(serializedData) outputFile.Flush() ' 刷新StreamWriter缓冲区 fs.Flush(True) ' 强制将文件流数据写入磁盘硬件 End Using End Using
内容的提问来源于stack exchange,提问作者tval
相关产品推荐
相关产品推荐

