【问题标题】:Ensuring whether file is copied successfully确保文件是否复制成功
【发布时间】:2015-07-01 12:23:29
【问题描述】:

我有一个文件要复制到某个位置。下面是代码sn-p -

//Document Status = Pending
var triggerFileWriter = new StringWriter();
triggerFileWriter.WriteLine("Only for test");
System.IO.File.WriteAllText(fullTriggerFilename, triggerFileWriter.ToString());
triggerFileWriter.Dispose();

if (System.IO.File.Exists(fullTriggerFilename))
{
    // Document Status = Processed
}

File.Exists 检查是否足以更新文档状态?
我不担心文件没有被复制并且文件状态没有更新。因为每 10 分钟有一个计时器作业运行,所以“待处理”项目将在下一次运行时自动拾取。

文件复制是否有可能被中断 - 这可能导致文件但实际上没有完全复制? 如果发生这种情况,我可以对我的代码进行哪些更改来解决。

谢谢!

【问题讨论】:

  • 写缓存,所以你必须flush 来确保它是真正安全的。当然,除了在WriteAllText 期间没有出现异常。
  • @Sinatr Flush 也不再等待 HDD 物理保存数据。在现代系统上,除非您有检查文件完整性的方法或依赖允许创建原子文件的文件系统(如 NTFS),否则根本无法确定。更重要的是,它并没有解决 OP 的问题——他不需要确保文件被正确写入,他只需要知道他现在要处理的文件是否需要处理。跨度>
  • @Luaan,你检查了我评论中的链接问题吗?
  • @Sinatr 是的。 FlushFileBuffers still 不能确保文件被物理写入。 OS 也无法强制 HDD 保存内部缓冲区。确实,它强制 Windows 将数据发送到 HDD,但 HDD 有自己的内部缓存。 FlushFileBuffers 的用途非常小众 - 对于那些想要感觉比实际控制更多的人来说:D
  • @Luaan,HDD 内部缓存 是关键。操作系统功能可能不会走那么远(和/或一些制造商无论如何都会欺骗它以获得更高的基准)。你说的对。当数据完整性可能是最高优先级时,我不会考虑性能,但刷新根本不起作用。 UPS 也可能发生故障(它可能与电源故障同时发生故障^^)。剩下的唯一方法是使用File.Exists,但提供另一种数据完整性方式,例如making backups.

标签: c#


【解决方案1】:

嗯,唯一确定的方法是将整个文件逐字节与您尝试写入的文件进行比较。当然,这并不便宜 - 无论如何,您都可以轻松地覆盖文件。

在 NTFS 上,没有正确“提交”的文件基本上会被删除,所以 File.Exists 很好。使用例如时可能不是这种情况。 FAT-32,或通过网络文件系统保存时。

在这种情况下,文件大小可能会有所帮助 - 除非您提前预先分配文件(这是一种很好的性能做法)。即使没有预先分配,文件大小也很可能正确,但仍然缺少数据。

【讨论】:

  • 感谢您的回复。实际上,该文件正在通过网络文件系统复制到另一台服务器。我可以依赖 File.Exists 吗?
  • @iniki 这主要取决于您是否也可以控制远程端。如果是带有 NTFS 的 Windows 服务器,你应该是安全的。
【解决方案2】:

您可以对原始文件使用诸如SHAMD5 之类的哈希函数并将其存储。然后对复制的文件应用相同的哈希函数并比较两个哈希。它们必须相同。

【讨论】:

    【解决方案3】:

    您正在调用File.WriteAllText 方法。这意味着您的工作将完成,否则您将获得例外。因此,您可以得到 .NET I/O API 提供的文件被正确写入的保证。

    但您永远无法保证它存在于某些资源中。所以你不需要打电话给File.Exists。只是不要依赖这个。一切都有可能发生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-23
      • 1970-01-01
      • 2015-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-06
      • 2017-01-26
      相关资源
      最近更新 更多