在Windows 10 IOT

时间:2017-06-26 00:28:42

标签: c# io windows-10-iot-core windowsiot

我的团队需要一种防弹方式来保存Windows 10 IOT上的文件(小于100kb)。

文件无法损坏,但如果由于电源关闭等原因导致保存失败,则可以放弃最新版本。

由于文件IO发生了重大变化(不再是File.Replace),我们不确定如何实现它。

我们可以看到:

var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists);
await Windows.Storage.FileIO.WriteTextAsync(file, data);

是可靠的不可靠的(它在停止调试或重置设备时反复出现故障。)我们最终得到一个损坏的文件(满了零)和一个旁边的.tmp文件。我们可以恢复这个.tmp文件我不相信我们应该将我们的解决方案建立在未记录的行为上。

我们想尝试的一种方式是:

var tmpfile = await folder.CreateFileAsync(fileName+".tmp",
                               CreationCollisionOption.ReplaceExisting);
await Windows.Storage.FileIO.WriteTextAsync(tmpfile, data);

var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists);

// can this end up with a corrupt or missing file?
await tmpfile.MoveAndReplaceAsync(file); 

总之,是否有一种安全的方法可以将某些文本保存到永远不会损坏文件的文件中?

2 个答案:

答案 0 :(得分:0)

不确定是否有最好的做法,但如果需要自己想出一些东西:

我会做一些事情,比如计算校验和并将其与文件一起保存。

下次保存时,请不要覆盖它,而是将其保存在前一个旁边(应该是#34;已知良好"),并在验证新的之后删除前一个保存已成功完成(连同校验和)

另外我会假设重命名操作不应该破坏文件,但我还没有研究过

答案 1 :(得分:0)

本文有一个很好的解释:Best practices for writing to files介绍了在UWP中写入文件所涉及的基本过程。

突出显示以下常见问题:

  • 部分写入文件。
  • 应用程序在调用其中一种方法时收到异常。
  • 操作会留下 .TMP 文件,其文件名与目标文件名相似。

在与convenience-vs-control进行权衡的讨论中不容易得出的结论是,尽管创建或编辑操作更容易失败,但由于它们做很多事情,而重命名操作则容错得多。他们实际上并没有在文件系统周围写位。

您建议先创建一个临时文件,该建议是正确的并且可能对您有好处,但是使用MoveAndReplaceAsync意味着如果目标文件已经存在,您仍然容易遇到这些已知问题。

  

UWP将在文件系统上使用事务模式,并可能创建源文件和目标文件的各种备份副本。

您可以通过在调用MoveAndReplaceAsync之前删除原始文件来控制最后一个元素,或者如果临时文件位于同一文件夹中,则可以简单地使用RenameAsync来控制最终元素减少故障面积。

@hansmbakker在这方面有一个答案,如何确定文件写入成功取决于您,但是如果需要将繁重的写入操作隔离开并在覆盖原始文件之前进行验证,则是一个好主意防弹


关于失败

使用FileIO Append 变体形式的 .TMP 时,我观察到很多 .TMP 文件。文件具有追加之前的原始文件的内容,但是实际文件并不总是具有所有原始客户端,有时是新旧内容的混合,有时是

  

以我的经验,当您对写入操作的整个调用结构是异步的并且正确等待管道时,UWP文件写入非常可靠。 AND ,您将采取步骤确保在任何时间点只有一个进程试图访问同一文件。

当您尝试从同步上下文中操作文件时,我们可以开始看到已识别出的“不可靠”性质,这种情况发生在很多代码中,这些代码正在从旧的同步操作过渡到更新的 Async < / em> FileIO操作的变体。

确保调用您的write方法的代码是非阻塞的并且可以正确等待,这将使您能够捕获可能引发的任何异常

对于我们传统上具有同步意识的开发人员来说,尝试使用lock(){}模式来确保对文件的单一访问是很常见的,但是您不能轻易在awaitlock内尝试尝试这样做经常成为UWP文件写入问题的根源。

如果您的代码具有锁定机制以确保对文件的单例访问,请以不同的方式阅读这些文章,它们虽然年代久远,但却是一个很好的资源,涵盖了从传统的同步C#开发人员到异步和并行开发。

  

其他时候,我们遇到同步约束的时候是Event或Timer或Dispose上下文是首先写入文件的触发器。有多种不同的技术可以参与其中,如果您认为这可能是导致您的问题的原因,请发布另一个涵盖该方案的问题。 :)