C#循环调用File.WriteAllBytes创建多文件时部分文件未生成问题
问题解答
你完全不需要用异步操作解决这个问题,这个现象和磁盘写入时序没有任何关系。File.WriteAllBytes是同步方法,方法执行完成返回时,就已经完成了全部字节写入、文件流关闭的操作,不存在操作系统还没写完就执行下一行代码的情况。
真正的问题出在你的文件名生成逻辑:
- 你在for循环内部每次迭代都新建了一个
Random实例。.NET Framework中Random的无参构造函数以系统时钟的毫秒级时间戳作为种子,而循环运行速度远快于系统时钟的更新频率,短时间内创建的多个Random实例会拿到完全相同的种子,生成一模一样的随机数 - 相同文件名的文件会被后续写入操作直接覆盖,最终表现为部分文件"写入失败"
- 你打断点的时候程序暂停,时间已经推进,每次新建的
Random拿到的种子不同,生成的文件名不重复,自然所有文件都能正常写入,这和你观察到的现象完全吻合。
修复方法
只需要做两个小改动即可:
- 把
Random实例的初始化移到循环外面,整个写入过程只实例化一次 - 建议在文件名中加入循环索引,彻底杜绝随机数碰撞导致的重名覆盖问题,路径拼接优先用
Path.Combine避免转义错误
修复后的代码参考:
private string WriteJpegs(string photoDate, List<Photo> photos) { Random rnd = new Random(); string saveDir = "PhotoFolder\\"; // 自动创建不存在的目录,避免首次运行报错 if (!Directory.Exists(saveDir)) { Directory.CreateDirectory(saveDir); } for (int i = 0; i < photos.Count; i++) { int randomNum = rnd.Next(1, 20000000); // 加循环索引i,彻底避免文件名重复 string fileName = $"{photoDate}_{i}_{randomNum}.jpg"; string fullSavePath = Path.Combine(saveDir, fileName); byte[] imageBytes = Convert.FromBase64String(photos[i].ImageData64); File.WriteAllBytes(fullSavePath, imageBytes); } return saveDir; }
改完之后不需要加任何延时、断点,所有文件都能正常写入。
内容的提问来源于stack exchange,提问作者pvitt
相关产品推荐
相关产品推荐

