有没有什么替代“截断”听起来更安全?

时间:2012-02-25 11:11:44

标签: c# file-io

我有一个应用程序在启动时从文件读取链接列表 1 ,并在文件结束时将其写回文件。写回时我选择truncate作为文件模式。但是,truncate对我来说听起来有点危险,因为它首先清除了整个内容。因此,如果出现问题,我就无法取回原来的东西了。还有更好的选择吗?

1:我使用链表,因为商品的顺序可能会改变。因此我稍后使用truncate来更新整个文件。


正如他第一次指出File.Replace()时,正确的答案声誉归于汉斯,尽管目前还没有适用于Silverlight。

4 个答案:

答案 0 :(得分:5)

写入新的临时文件。完成并对结果满意后,删除旧文件并将新临时文件重命名/复制到原始文件的位置。这样,如果出现任何问题,您不会丢失数据。

正如Hans Passants的回答所指出的那样,在替换原始文件时,您应该使用File.Replace来获得最大的稳健性。

答案 1 :(得分:3)

.NET框架很好地涵盖了这一点。使用File.Replace()方法。它使用另一个文件的内容安全地替换原始文件的内容,如果文件系统有任何问题,请保留原文。这是一个比upvoted答案更好的鼠标陷阱,当原始文件上有待删除时它们会失败。

有一个重载可让您控制原始文件是否保留为备份文件。最好是让函数创建备份,它会显着增加函数在另一个进程锁定文件时成功的几率,这是最典型的故障模式。他们将保持对备份文件的锁定。当您在与原始驱动器相同的驱动器上创建中间文件时,该方法也最有效,因此您需要避免使用GetTempFileName()。生成文件名的好方法是Guid.NewGuid()。ToString()。

答案 2 :(得分:2)

稳健性的“最佳”替代方案是执行以下操作:

  1. 为您要保存到磁盘的数据创建文件
  2. 将数据写入新文件
  3. 执行任何必要的数据验证
  4. 删除原始文件
  5. 文件移至原始文件位置
  6. 您可以使用System.IO.Path.GetTempFileName为您提供一个唯一命名的临时文件,用于第1步。

答案 3 :(得分:2)

您曾考虑使用truncate,因此我假设您的输入数据总是重新生成,因此....

  1. 尝试...抓住将原始文件重命名为'originalname_day_month_year.bak'
  2. 使用新数据为您的文件写新文件。
  3. 通过这种方式,您不必担心松动任何东西,作为副作用,您可以拥有以前数据的备份副本。如果不需要该备份,您始终可以删除备份文件。