C# 将Web API数据保存到txt文件时末尾数据缺失如何解决
问题根因
- 异步写操作未等待完成就释放文件流:调用
fs.WriteAsync时没有等待异步操作执行完成,using代码块执行结束后会立即释放FileStream对象,此时写入操作还没完成文件就被关闭,自然会出现末尾数据缺失。 - 写入字节数参数错误:
WriteAsync第三个参数要求传入待写入的字节数,但代码中传的是原字符串strContent的字符长度。UTF8编码下一个字符可能对应1~4个字节,这个值会小于实际编码后得到的title字节数组的长度,导致部分字节没有被写入文件。 - 隐性问题1:后续循环逐行写文件的逻辑冗余,每次遍历都调用
File.WriteAllLines会反复覆盖文件,效率极低还容易引发IO冲突。 - 隐性问题2:
FileService的ReturnBinLocation方法硬编码截取路径字符串,兼容性极差,一旦路径格式变化就会返回错误路径。
修复方案
核心写文件逻辑修复(二选一即可)
- 改用同步写入(最简单稳定):
using (var fs = FileService.CreateFile("filename.txt")) { var title = new UTF8Encoding(true).GetBytes(strContent); fs.Write(title, 0, title.Length); // 同步写入,传入字节数组的实际长度 }
- 正确使用异步逻辑:
// 注意方法签名要改成 async Task GetData() using (var fs = FileService.CreateFile("filename.txt")) { var title = new UTF8Encoding(true).GetBytes(strContent); await fs.WriteAsync(title, 0, title.Length); // 等待异步写入完成,传入正确的字节长度 }
冗余逻辑优化
已经拿到完整的接口返回字符串strContent,不需要先写文件再读出来再逐行写入新文件,直接操作原字符串即可,可删除以下冗余代码:
var file = File.ReadAllLines(FileService.ReturnBinLocation("filename.txt")); var results = new List<string>(); for (var a = 0; a < file.Length; a++) { results.Add(file[a]); File.WriteAllLines(data, results); }
直接处理原字符串:
var split = strContent.Replace('\n', '|').TrimEnd('|').Split('|');
路径处理逻辑修复
修改FileService的ReturnBinLocation方法,避免硬编码截取字符串:
public static string ReturnBinLocation(string fileName) { var binPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); return Path.Combine(binPath, fileName); }
内容的提问来源于stack exchange,提问作者Vanessa Kensington
相关产品推荐
相关产品推荐

