获取当前文件长度/FileInfo.Length缓存和陈旧信息写。我必须不断更新每个文件长度的记录,我将其用于其他目的。如果文件长度与上次更新中确定的长度不同,则每15秒调用一次Update方法来更新文件的属性。更新方法如下所示:vardirectoryInfo=newDirectoryInfo(archiveFolder);vararchiveFiles=directoryInfo.GetFiles().OrderByDescending(f=>f.CreationTimeUtc);foreach(FileInfofiinarchiveFiles){//检查文件是否已经存在于之前的更新中varorigFileProps=cachedFiles.GetFileByName(fi.FullName);if(origFileProps!=null&&fi.Length==origFileProps.EndOffset){//文件长度不变}else{//更新此文件的属性//将文件的EndOffset设置为当前文件长度}}我知道DirectoryInfo.GetFiles()预填充许多FileInfo属性,包括Length-只要更新之间没有缓存(缓存信息不应超过15秒)问题,这就很好。我假设每个DirectoryInfo.GetFiles()调用都会生成一组新的FileInfo,然后使用FindFirstFile/FindNextFileWin32API来填充所有新信息。但事实似乎并非如此。很少,但最终肯定会遇到写入文件的文件长度一次有5、10甚至20分钟没有更新的情况(如果重要,在Windows2008Serverx64上测试过)。当前的解决方法是调用fi.Refresh()强制更新每个文件信息。这在内部似乎委托给GetFileAttributesExWin32API调用来更新文件信息。虽然手动强制刷新的成本是可以容忍的,但我宁愿理解为什么我一开始就得到陈旧的信息。什么时候生成FileInfo信息,它与调用DirectoryInfo.GetFiles()有什么关系?是否有我没有完全掌握的文件I/O缓存层?RaymondChen现在就这个问题写了一篇非常详细的博文:为什么报告的文件大小不正确?在NTFS中,文件系统元数据不是目录条目的属性,而是文件的属性,其中一些元数据被复制到目录条目中作为改进目录枚举性能的调整。FindFirstFile等函数报告目录条目,并通过放置FAT用户习惯于“免??费”获取的元数据,避免目录列表比FAT慢。目录枚举功能报告最后更新的元数据,如果目录条目陈旧,则该元数据可能与实际元数据不对应。本质上它归结为性能:从DirectoryInfo.GetFiles()和下面的FindFirstFile/FindNextFileWin32API收集的目录信息出于性能原因被缓存,以保证在NTFS中比用于更好地获取目录信息的旧FAT具有更好的性能。准确的文件大小信息只能通过直接调用文件上的GetFileSize()来获取(.NET调用FileInfo上的Refresh()或通过直接从文件名获取FileInfoGetFileSize()-或者打开和关闭导致更新的文件流要传播到目录元数据缓存的信息。后一种情况解释了为什么在写入过程关闭文件时立即更新文件大小。这也解释了Windows2003Server中似乎不存在该问题-刷新时缓存更频繁地复制文件信息-Windows2008Server不再如此:至于频率,答案有点复杂。从WindowsVista(及其相应的WindowsServer版本,我不知道,但我相信你可以查一下,“你”我的意思是“YuhongBao”)开始,NTFS文件系统执行这种礼貌的复制关闭文件对象的最后一个句柄。早期版本的NTFS在刷新缓存时在文件打开时复制数据,这意味着它经常根据不可预测的时间表发生。此更改的结果是目录条目现在更新的频率较低,因此最后更新的文件大小比现在更新。内容丰富,建议阅读全文!我认为您应该使用FileSystemWatcher并订阅Changed事件。当指定的文件系统条目更改时触发。我同意Wojteq的观点,即使用FileSystemWatcher类是更好的解决方案。它在文件或目录的不同属性更改时公开事件(例如他引用的Change事件),这是比当前轮询解决方案好得多的解决方案。要回答有关为什么刷新需要不同时间来反映文件大小更改的问题,答案与Windows操作系统的底层虚拟内存管理器有关。当执行文件I/O时,它实际上是对内存映射文件进行更新;这是操作系统管理的文件的缓冲副本。因此,Windows控制缓冲数据何时写入磁盘。无法预测特定缓冲数据何时会物理写入磁盘。这意味着更新文件流会将这些更新放在缓冲区中。如果您正在Flush()流缓冲区更新应立即写入磁盘,如果您关闭流然后它将在流关闭后从缓冲区写入磁盘,如果流保持打开状态,则Windows决定将缓冲数据写入磁盘。以上就是C#学习教程:获取当前文件长度/FileInfo。代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
