8

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

我想知道的是:如果文件当前正在由第三方应用程序写入(或在被 Windows 复制到文件夹的过程中),而我创建FileInfo对象或访问它的属性?

4

3 回答 3

13

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

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

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

于 2013-01-06T13:20:57.790 回答
1

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

FileSystemInfo.LastWrite -> MSDN

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

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

于 2013-01-06T12:46:12.767 回答
0

没问题看msdn:

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

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

注意:

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

于 2013-01-06T12:47:02.160 回答