当我在一个正在被写入的文件上调用FileInfo(path).LastAccessTime
或FileInfo(path).LastWriteTime
时,它返回的是文件创建的时间,而不是文件最后一次被写入的时间(例如,文件被写入的时间)。现在)。
有没有办法得到这些信息?
***********我没有试过Refresh()
,但它也没有。返回文件开始写入的时间。静态方法也是如此,创建一个新的FileInfo
示例。
Codymanix可能有答案,但我没有运行Windows Server(使用Windows 7),我不知道在哪里测试设置。
**编辑2:**没有人觉得这个功能似乎不起作用很有趣吗?
7条答案
按热度按时间rn0zuynd1#
FileInfo
值只加载一次,然后缓存。要获取当前值,请在获取属性之前调用Refresh()
:获取当前值的另一种方法是使用
File
类上的静态方法:nbnkbykc2#
从Windows Vista开始,默认情况下不会更新上次访问时间。这是为了提高文件系统性能。您可以在这里找到详细信息:
https://techcommunity.microsoft.com/t5/storage-at-microsoft/disabling-last-access-time-in-windows-vista-to-improve-ntfs/ba-p/423328
要在计算机上重新启用上次访问时间,可以运行以下命令:
fsutil行为设置disablelastaccess 0
wkftcu5l3#
正如James所指出的LastAccessTime没有更新。
自Vista以来,LastWriteTime也经历了一个转折。当进程仍然打开文件并且另一个进程检查LastWriteTime时,它将在很长一段时间内看不到新的写入时间-直到进程关闭文件。
作为解决方法,您可以从外部进程打开和关闭该文件。完成后,您可以尝试再次读取LastWriteTime,这是最新的值。
文件系统隧道:
如果应用程序实现了类似滚动日志记录器的东西,它关闭文件,然后将其重命名为不同的文件名,那么您也会遇到问题,因为操作系统会记住“旧”文件的创建时间和文件大小,尽管您确实创建了一个新文件。这包括文件大小的错误报告,即使您从头开始重新创建log.txt,其大小仍为0字节。此功能称为OS文件系统隧道,它仍然存在于Windows 8.1中。一个如何解决这个问题的例子可以查看RollingFlatFileTracelistener from Enterprise Library。
您可以从cmd shell查看文件系统隧道在您自己的机器上的效果。
文件系统是一个状态机。如果您关心性能和正确性,那么保持状态正确同步是很困难的。
这种奇怪的隧道综合征显然仍然被这样的应用程序使用,例如。自动保存文件并将其移动到保存位置,然后在同一位置重新创建该文件。对于这些应用程序,为文件提供一个新的创建日期是有意义的,因为它只是被复制了。一些安装程序也会使用这样的技巧,将文件临时移动到不同的位置,然后在稍后写回内容,以通过一些文件存在检查来检查一些安装钩子。
um6iljoc4#
你有没有试过在访问属性之前调用
Refresh()
(以避免获取缓存值)?如果这不起作用,你有没有看过资源管理器同时显示的内容?如果资源管理器显示错误的信息,那么它可能是你不能真正解决的问题-例如,可能只有在文件句柄关闭时才更新信息。nsc4cvqm5#
Windows中有一个设置,有时特别是在服务器系统上设置,以便不设置文件的修改和访问时间以获得更好的性能。
8i9zcol26#
从MSDN:
第一次调用时,FileSystemInfo调用Refresh并返回API上的缓存信息以获取属性等。在后续调用中,必须调用Refresh以获取信息的最新副本。
FileSystemInfo.Refresh()
如果你的应用程序是一个做写,我认为你将不得不“接触”的文件设置LastWriteTime属性之间的每个缓冲区的数据写你自己。一些伪代码:
我不确定这会严重影响写性能。
mctunoxg7#
Tommy Carlier的回答让我思考……
一个可视化差异的好方法是分别运行下面的两个片段(我刚刚使用了LinqPAD),同时运行sysinternals进程监视器。
和
如果在运行第一个代码段时查看ProcessMonitor,您将看到LinqPAD进程对文件的重复和持续的访问尝试。第二个代码片段将执行文件的初始访问,您将在进程监视器中看到活动,之后很少看到活动。
但是,如果你去修改文件(我刚刚打开了我正在使用FileInfo监视的文本文件,并添加了一个字符并保存了),你会看到LinqPAD进程对进程监视器中的文件的一系列访问尝试。
这分别说明了两种不同方法的非缓存和缓存行为。
非缓存方法是否会在硬盘驱动器上磨损一个洞?!
编辑
我离开的时候感觉自己在测试中很聪明,然后在我的Windows服务中使用了FileInfo的缓存行为(基本上是坐在一个循环中,在进行处理之前说'Has-file-changed-has-file-changed...')
虽然这种方法在我的开发盒上工作,但它在生产环境中不起作用,即无论文件是否更改,进程都将继续运行。我最终改变了我的检查方法,只是使用GetLastAccessTime作为它的一部分。不知道为什么在生产服务器上会有不同的表现……但我在这一点上并不太担心。