【发布时间】:2018-12-07 08:01:05
【问题描述】:
我需要在我的项目中写一个大文件。
我学到了什么:
我不应该将大文件直接写入目标路径, 因为这可能会留下一个不完整的文件,以防应用在编写时崩溃。
相反,我应该写入一个临时文件并移动(重命名)它。 (称为原子文件操作)
我的代码 sn-p:
[NotNull]
public static async Task WriteAllTextAsync([NotNull] string path, [NotNull] string content)
{
string temporaryFilePath = null;
try {
temporaryFilePath = Path.GetTempFileName();
using (var stream = new StreamWriter(temporaryFilePath, true)) {
await stream.WriteAsync(content).ConfigureAwait(false);
}
File.Delete(path);
File.Move(temporaryFilePath, path);
}
finally {
if (temporaryFilePath != null) File.Delete(temporaryFilePath);
}
}
我的问题:
如果应用在
File.Delete和File.Move之间崩溃,该文件将会丢失。我可以避免这种情况吗?还有其他编写大文件的最佳实践吗?
对我的代码有什么建议吗?
【问题讨论】:
-
采用这种方法时需要注意的一点:如果 TEMP 文件夹与最终目标文件夹位于不同的驱动器上,那么
File.Move()实际上必须复制该文件,它是一个非常大的文件,可能会严重影响性能。 -
@Matthew 是的,我知道。在这种情况下,我有足够的理由断定目标文件夹和临时文件夹在同一个驱动器上。所以我只添加了
finally块进行确认(File.Move当源和目标位于不同的驱动器上时复制)。但如果我能避免性能问题,那就更好了。有什么解决办法吗?我对你的想法很感兴趣。 -
@SirRufo 感谢您提供的信息丰富的评论。我不知道
FileOptions.DeleteOnClose选项。恐怕我不明白如何将其应用于我的案例。你不能Move一个文件在关闭之前(因此在被删除之前)吗?如果你再帮我一些,我会被申请的...... -
好吧,我会写临时文件,复制到目的地(就像移动到不同的驱动器时一样)并删除临时文件。
标签: c# .net system.io.file