当我在正在写入的文件上调用FileInfo(path).LastAccessTime
或FileInfo(path).LastWriteTime
时,它返回创建文件的时间,而不是上次写入文件的时间(即现在)。
有没有办法获取这些信息?
编辑:到目前为止的所有回复。我没有尝试过Refresh()
,但也没有尝试过。我返回文件开始写入的时间。静态方法也是如此,并创建FileInfo
的新实例。
Codymanix可能有答案,但我没有运行Windows Server(使用Windows 7),我不知道设置的测试位置。
编辑2:没有人觉得这个功能似乎不起作用很有意思?
答案 0 :(得分:15)
FileInfo
值仅加载一次然后缓存。要获取当前值,请在获取属性前致电Refresh()
:
f.Refresh();
t = f.LastAccessTime;
获取当前值的另一种方法是使用File
类上的静态方法:
t = File.GetLastAccessTime(path);
答案 1 :(得分:8)
从Windows Vista开始,默认情况下不会更新上次访问时间。这是为了提高文件系统性能。你可以在这里找到详细信息:
要重新启用计算机上的最后访问时间,您可以运行以下命令:
fsutil behavior set disablelastaccess 0
答案 2 :(得分:4)
您是否尝试在访问该属性之前调用Refresh()
(以避免获得缓存值)?如果这不起作用,你看看资源管理器同时显示什么?如果资源管理器显示错误的信息,那么它可能是您无法真正解决的问题 - 例如,可能仅在文件句柄关闭时更新信息。
答案 3 :(得分:4)
来自MSDN:
首次调用时,FileSystemInfo 调用Refresh并返回 有关API的缓存信息 属性等。随后 打电话,你必须调用刷新来获取 最新的信息副本。
如果您的应用程序是写作的人,我认为您将不得不通过在您编写的每个数据缓冲区之间设置LastWriteTime属性来“触摸”该文件。一些伪代码:
while(bytesWritten < totalBytes)
{
bytesWritten += br.Write(buffer);
myFileInfo.LastWriteTime = DateTime.Now;
}
我不确定这会对写入性能产生多大影响。
答案 4 :(得分:4)
Windows中有一个设置,有时会在服务器系统上进行设置,因此不会设置文件的修改和访问时间以获得更好的性能。
答案 5 :(得分:4)
正如詹姆斯指出 LastAccessTime未更新。
自Vista以来,LastWriteTime也经历了一次扭曲。 当进程文件仍然打开而另一个进程检查LastWriteTime时,它将长时间看不到新的写入时间 - 直到进程关闭文件为止。
作为一种解决方法,您可以从外部进程打开和关闭该文件。完成后,您可以尝试再次读取LastWriteTime,这是最新值。
文件系统隧道:
如果某个应用程序实现类似滚动记录器的操作,它会关闭该文件,然后将其重命名为不同的文件名,那么您也会遇到问题,因为操作系统会记住“旧”文件的创建时间和文件大小。你确实创建了一个新文件。这包括错误的文件大小报告,即使您从头开始重新创建log.txt,其大小仍为0字节。此功能称为操作系统文件系统隧道,它仍然存在于Windows 8.1中。如何解决此问题的示例请查看RollingFlatFileTracelistener from Enterprise Library。
您可以从cmd shell中查看文件系统隧道在您自己的计算机上的效果。
echo test > file1.txt
ren file1.txt file2.txt
Wait one minute
echo test > file1.txt
dir /tc file*.txt
...
05.07.2015 19:26 7 file1.txt
05.07.2015 19:26 7 file2.txt
文件系统是状态机。如果你关心性能和正确性,保持状态正确同步是很难的。
这种奇怪的隧道综合症显然仍被申请人使用,例如自动保存文件并将其移动到保存位置,然后在同一位置再次重新创建该文件。对于这些应用程序,为文件提供一个新的创建日期是有意义的,因为它只是复制了。一些安装程序也会使用这样的技巧将文件临时移动到不同的位置并稍后将内容写回以通过某些文件存在检查某些安装挂钩。
答案 6 :(得分:0)
可视化差异的一个好方法是单独运行两个片段(我刚刚使用LinqPAD),同时运行sysinternals Process Monitor。
while(true)
File.GetLastAccessTime([file path here]);
和
FileInfo bob = new FileInfo(path);
while(true){
string accessed = bob.LastAccessTime.ToString();
}
如果在运行第一个代码段时查看Process Monitor,您将看到对LinqPAD进程的文件进行重复且持续的访问尝试。第二个代码段将对文件进行初始访问,您将在其中看到进程监视器中的活动,然后很少。
但是,如果你去修改文件(我刚刚打开了我正在使用FileInfo进行监控的文本文件并添加了一个字符并保存),您将看到LinqPAD进程对进程监视器中的文件进行一系列访问尝试。 / p>
这分别说明了两种不同方法的非缓存和缓存行为。
非缓存方法是否会在硬盘中出现漏洞?!
修改强>
我在测试中感觉很聪明,然后在我的Windows服务中使用了FileInfo的缓存行为(基本上是坐在一个循环中说'Has-file-changed-has-file-changed ...'之前做处理)
虽然这种方法适用于我的开发箱,但它在生产环境中无效,即无论文件是否发生变化,流程都会继续运行。我最终改变了我的检查方法,并且只使用了GetLastAccessTime作为其中的一部分。不知道为什么它会在生产服务器上表现不同......但我现在并不太在意。