在C#中缓存FileInfo属性
从FileInfo.Name
属性的MSDN文档中,我看到该属性的数据在第一次被调用时被缓存,并且随后将仅使用Refresh
方法进行更新。
我有以下问题,我在文档中找不到或不太清楚:
-
是否同时缓存了所有属性的数据?
-
是在创建
FileInfo
时调用Refresh
方法,还是仅在第一次调用属性时调用? -
如果我调用了一个属性,例如
Name
属性,并且它被称为Refresh
,则会首次调用另一个属性(例如DirectoryName
属性)使其再次调用Refresh
,或者仅由访问的第一个属性调用它在整个class级(见问题#1 )? -
我可以通过手动调用
Refresh
预缓存所有属性吗? (假设它没有在构造对象时预先缓存) -
是否手动调用
Refresh
会导致预先缓存的属性(例如CreationTime
)也被刷新?
-
猜猜是的。 对于
FileInfo
,仅仅获取您之前获取的属性似乎是一种自我挫败的“优化”,特别是当它们可以(并且可能是)在一次API调用中获取时。 -
文档调用提供已经缓存的
FileInfo
的DirectoryInfo
方法的事实强烈地(对我来说,无论如何),简单地构造FileInfo
不会缓存任何东西。 这是有道理的 – 如果你直接构造一个FileInfo
,它可能会引用一个尚不存在的文件(例如你计划创建它),而所有返回缓存的FileInfo
的方法都是指存在于该文件中的文件。快照的时间,假设您将至少使用其中一些 。 -
不,通过我对问题1的回答。这就是为什么Refresh方法存在的原因。
-
我想是这样(见答案1)。
-
是。 见答案3。
如果从以下任何DirectoryInfo方法返回FileSystemInfo对象的当前实例,则会预缓存CreationTime属性的值:
- GetDirectories
- 的GetFiles
- GetFileSystemInfos
- EnumerateDirectories
- EnumerateFiles
- EnumerateFileSystemInfos
要获取最新值,请调用Refresh方法。
如果FileSystemInfo对象中描述的文件不存在,则此属性将返回到公元1601年1月1日午夜12点(CE)协调世界时(UTC),调整为当地时间。
NTFS格式的驱动器可以在短时间内缓存文件元信息,例如文件创建时间。 此过程称为文件隧道。 因此,如果要覆盖或替换现有文件,可能需要显式设置文件的创建时间。
( MSDN )
在内部, Refresh
调用标准的Win32API,从而填充所有属性。
[...] flag2 = Win32Native.GetFileAttributesEx(path, 0, ref data);
访问指定为Refresh的任何属性会导致完全刷新,例如:
public DateTime LastAccessTimeUtc { [SecuritySafeCritical] get { if (this._dataInitialised == -1) { this._data = default(Win32Native.WIN32_FILE_ATTRIBUTE_DATA); this.Refresh(); } [...]