【问题标题】:Is it safe to create a FileInfo on a file that is currently being written to?在当前正在写入的文件上创建 FileInfo 是否安全?
【发布时间】:2013-01-06 12:38:17
【问题描述】:

在我的应用程序(C# 4.5 winforms 应用程序)中,我定期检查文件夹的内容并将找到的任何文件的详细信息存储到数据库中。在这个例程中,我使用new FileInfo(path) 创建了一个FileInfo 实例,并读取了CreationTime、LastWriteTime、LastAccessTime、Length 和Attributes 的属性。我从不在 FileInfo 实例上调用任何方法。

我想知道的是:如果文件当前正在被第三方应用程序写入(或正在被 Windows 复制到文件夹中),那么在我创建文件时是否存在损坏、锁定或运行时错误的风险FileInfo 对象或访问它的属性?

【问题讨论】:

    标签: c# file fileinfo


    【解决方案1】:

    是的,这是“安全的”。这是在非常底层的文件系统驱动程序中处理的。 FAT 或 NTFS 等常见文件系统上的文件在磁盘上有两个不同的结构。首先是目录条目,它存储有关文件的元数据。就像名称、时间戳、属性和长度一样。实际的文件数据存储在其他地方,即存储文件数据的集群链。

    FileInfo 专门为您提供文件的元数据。文件数据更加敏感,在进程写入文件时很容易发生变化。值得注意的是,您可以使用 FileShare 选项锁定对文件数据的访问。但是没有办法锁定元数据。因此,您始终可以获取文件的 FileInfo,而不管其他进程正在对该文件执行什么操作。

    当然,当进程写入文件时,实际的 FileInfo 属性可能会发生变化。它们懒惰地更新,尤其是 LastAccessTime 属性。如果您想确保您拥有无法更改的准确信息,那么您需要获得文件的锁定。通过使用 FileShare.Read 或 FileShare.None 打开文件来执行此操作。这确保了只要您打开了文件,就没有其他进程可以打开文件进行写入。请注意, 很容易抛出 IOException,只有在没有其他进程在您之前并打开文件进行写入时,您才会获得锁。

    【讨论】:

    • 非常感谢您的详细解释。让我相信我的代码是安全的。如果我想使用 FileShare.None 写入文件,我会单独检查独占访问权限,但在这种特殊情况下,我只需要元数据,现在我可以放心地阅读它,而不会损坏正在保存的文件写给。
    【解决方案2】:

    不,它们不在您使用的上下文中。

    来自FileSystemInfo.LastWrite -> MSDN

    注意此方法可能返回不准确的值,因为它使用的本机函数的值可能不会被操作系统持续更新。

    但是想象一下,他们正在返回最新的值。如果您已经使用了该值(取决于时间),并且在那之后文件被覆盖,那么您最后访问的值将变得错误/损坏。所以这没有意义。

    【讨论】:

      【解决方案3】:

      没问题看msdn:

      http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx

      线程安全 此类型的任何公共静态(在 Visual Basic 中为 Shared)成员都是线程安全的。不保证任何实例成员都是线程安全的。

      和注意:

      第一次检索属性时,FileInfo 调用 Refresh 方法并缓存有关文件的信息。在后续调用中,您必须调用 Refresh 以获取信息的最新副本。

      【讨论】:

      • 但是当文件对象不断被修改时会出现竞争。
      • 他们在他们的水平上处理它并向你保证,只要你使用静态方法,你就会得到一个安全的结果。这可能不是最新的,但数据不会被损坏。
      猜你喜欢
      • 2015-05-12
      • 2015-12-29
      • 1970-01-01
      • 2011-08-15
      • 2020-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多