【发布时间】:2011-10-19 21:06:31
【问题描述】:
我正在跟踪一个文件夹及其文件长度,其中至少有一个文件仍在被写入。
我必须不断更新我用于其他目的的每个文件长度的记录。
Update 方法每 15 秒调用一次,如果文件长度与上次更新中确定的长度不同,则更新文件的属性。
更新方法如下所示:
var directoryInfo = new DirectoryInfo(archiveFolder);
var archiveFiles = directoryInfo.GetFiles()
.OrderByDescending(f=>f.CreationTimeUtc);
foreach (FileInfo fi in archiveFiles)
{
//check if file existed in previous update already
var origFileProps = cachedFiles.GetFileByName(fi.FullName);
if (origFileProps != null && fi.Length == origFileProps.EndOffset)
{
//file length is unchanged
}
else
{
//Update the properties of this file
//set EndOffset of the file to current file length
}
}
我知道DirectoryInfo.GetFiles() 正在预填充许多FileInfo 属性,包括Length - 只要在更新之间 之间不进行缓存,这是可以的(缓存信息不应超过 15 秒)。
我假设每个DirectoryInfo.GetFiles() 调用都会生成一组新 FileInfos,然后使用FindFirstFile/FindNextFile Win32 API 填充新信息。但这似乎并非如此。
很少,但最终肯定会遇到这样的情况,即写入的文件的文件长度一次没有更新 5、10 甚至 20 分钟(测试在 Windows 2008 Server x64 上完成,如果这很重要)。
当前的解决方法是调用fi.Refresh() 来强制更新每个文件信息。这在内部似乎委托给GetFileAttributesEx Win32 API 调用来更新文件信息。
虽然手动强制刷新的成本是可以容忍的,但我宁愿理解为什么我首先会得到陈旧的信息。 FileInfo 信息是何时生成的,它与 DirectoryInfo.GetFiles() 的调用有何关系?下面是否有我没有完全掌握的文件 I/O 缓存层?
【问题讨论】: