C# 在当前正在写入的文件上创建FileInfo安全吗?

C# 在当前正在写入的文件上创建FileInfo安全吗?,c#,file,fileinfo,C#,File,Fileinfo,在我的应用程序(C#4.5 winforms应用程序)中,我定期检查文件夹的内容,并将找到的任何文件的详细信息存储到数据库中。在这个例程中,我使用newfileinfo(path)创建一个FileInfo实例,并读取属性CreationTime,LastWriteTime,LastAccessTime,Length和属性。我从不在FileInfo实例上调用任何方法 我想知道的是:当我创建FileInfo对象或访问其属性时,如果第三方应用程序正在写入文件(或正在通过Windows复制到文件夹),是

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


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

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

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

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

没问题,请参见msdn:

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

注意:

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

是的,这是“安全的”。这是在一个非常低的级别上处理的,即文件系统驱动程序。常见文件系统(如FAT或NTFS)上的文件在磁盘上有两种不同的结构。首先是目录条目,它存储关于文件的元数据。例如名称、时间戳、属性和长度。实际的文件数据存储在其他位置,即存储文件数据的集群链

FileInfo专门为您提供文件的元数据。文件数据更加敏感,在进程写入文件时极易发生更改。值得注意的是,您可以使用FileShare选项锁定对文件数据的访问。但是没有办法锁定元数据。因此,无论其他进程如何处理文件,都可以始终获取文件的FileInfo


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

但是,当文件对象不断被修改时,会出现竞争。他们会按照自己的级别处理它,并向您保证,只要使用静态方法,您将获得安全的结果。这可能不是最新的,但数据不会被腐蚀。非常感谢您的详细解释。让我相信我的代码是安全的。如果要写入文件,我会使用FileShare.None单独检查独占访问权限,但在这种情况下,我只需要元数据,现在我可以放心地读取它,而不会损坏正在写入的文件。