如何确保数据在保存到文件时不会损坏
本文关键字:存到文件 损坏 数据 何确保 确保 | 更新日期: 2023-09-27 18:12:59
我对c#比较陌生,所以请原谅我。
我正在编写一个商业应用程序(c#, . net 4),需要可靠。数据将存储在文件中。文件将被定期修改(重写),因此我担心在保存数据时可能会出现问题(断电,应用程序被杀死,系统冻结,…),这将(我认为)导致文件损坏。我知道没有保存的数据会丢失,但是我不能丢失已经保存的数据(因为损坏或…)。
我的想法是每个文件有两个版本,每次重写最旧的文件。然后,如果我的应用程序意外结束,至少一个文件仍然应该是有效的。
这是一个好方法吗?还有什么我能做的吗?(数据库不是一个选项)
感谢您的回答。
与其"总是写入最老的文件",不如使用"安全文件写入"技术:
(假设您希望最终将数据保存到foo.data
,并且该名称的文件包含以前的有效版本。)
- 向
foo.data.new
写入新数据 - 将
foo.data
重命名为foo.data.old
- 将
foo.data.new
重命名为foo.data
- 删除
foo.data.old
在任何时候总是得到至少一个有效文件,并且您可以仅从文件名中判断哪个是要读取的文件。当然,这是假设您的文件系统自动处理重命名和删除操作。
- 如果
foo.data
和foo.data.new
存在,加载foo.data
;foo.data.new
可能被破坏(例如在写过程中断电) - 如果
foo.data.old
和foo.data.new
存在,两者都应该是有效的,但不久之后有些东西就死了-你可能想要加载foo.data.old
版本 - 如果
foo.data
和foo.data.old
存在,那么foo.data
应该没问题,但是又出了问题,或者可能是文件无法删除。
或者,简单地总是写入新文件,包括某种单调递增的计数器—这样您就不会因为错误的写入而丢失任何数据。最好的方法取决于你写的是什么。
您也可以使用File.Replace
,它基本上为您执行最后三个步骤。(如果不想保留备份,请输入null
作为备份名称)
很多程序都使用这种方法,但通常,它们会做更多的复制,以避免人为错误。
例如,Cadsoft Eagle(一个用于设计电路和印刷电路板的程序)对同一个文件做多达9个备份副本,称为文件。b # 1…file.b # 9
你可以做的另一件事是哈希:在文件末尾附加一个像CRC32或MD5这样的哈希。当你打开它,你检查CRC或MD5,如果他们不匹配的文件是损坏的。这也将使您免受那些意外或故意试图用其他程序修改您的文件的人的侵害。这也会给你一种方法来知道是否硬盘驱动器或u盘损坏。
当然,保存文件操作越快,丢失数据的风险就越小,但是您不能确保在写入过程中或之后不会发生任何事情。
考虑到硬盘驱动器,usb驱动器和windows操作系统都使用缓存,这也意味着,如果你完成写入数据可能是操作系统或磁盘本身仍然没有物理地将它写入磁盘。
你可以做的另一件事,保存到一个临时文件,如果一切正常,你将文件移动到真正的目标文件夹,这将减少半文件的风险。
你可以把这些技巧混合在一起。
原则上有两种流行的方法:
- 让你的文件格式基于日志,也就是说,不要在通常的保存情况下覆盖,只是在末尾附加更改或最新版本。
或
- 写入新文件,将旧文件重命名为备份文件,并将新文件重命名为其位置
第一种方法给您留下了更多的开发工作,但如果您将小的更改保存到大文件(Word曾经这样做过),也有使保存更快的优点。