为何PowerShell中LastWriteTime仅在读取文件时才更新?
LastWriteTime仅在读取文件时才更新?
我有一个持续写入的日志文件,该日志会定期滚动并生成新文件名的日志。我写了一段脚本,用来获取匹配指定掩码的最新文件:
gci $mask | Sort-Object LastWriteTime -Descending | Select-Object -First 1
但这段脚本无法正常工作:日志滚动到新文件后,程序会先打开新文件,再往旧文件里写入收尾内容,导致旧文件的LastWriteTime比新文件的创建时间还要晚。之后PowerShell始终将新文件识别为0字节文件,它的LastWriteTime也从不更新——哪怕文件已经被持续写入了好几个小时。
我做了几个测试:
- 用文本编辑器打开读取新文件后,它的时间戳和文件大小会立即更新;
- 但对文件对象或目录调用
Refresh()方法,数据完全没变化:
PS C:\Users\user\Documents> gci $mask |Sort-Object LastWriteTime -Descending | Select-Object -First 1 Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 16/10/2024 13:58:33 623766 ResponderService_F0711118_7268_20241016.log PS C:\Users\user\Documents> gci $mask |Sort-Object LastWriteTime -Descending | % {$_.Refresh()} PS C:\Users\user\Documents> gci $mask |Sort-Object LastWriteTime -Descending | Select-Object -First 1 Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 16/10/2024 13:58:33 623766 ResponderService_F0711118_7268_20241016.log
- 但如果读取文件内容并输出到
$null,LastWriteTime就会更新:
PS C:\Users\user\Documents> gci $mask |Sort-Object LastWriteTime -Descending | gc > $null PS C:\Users\user\Documents> gci $mask |Sort-Object LastWriteTime -Descending | Select-Object -First 1 Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 16/10/2024 14:02:56 636468 ResponderService_F0711118_7268_20241016.log
文件每隔几秒就会有写入操作,所以肯定不是写入缓冲区刷新的问题;哪怕写入了几小时、几十兆的日志,文件属性依然不更新,只有读取后才会立刻更新,而且能看到最近几秒的日志时间戳。
请问这是什么原因?我有没有操作错误?这种仅在读取时才更新的LastWriteTime有什么作用?
编辑补充
SeanH和Eugene指出这是NTFS文件系统的问题。如果有人遇到类似情况,我现在使用的脚本如下:
foreach ($s in $mr_servers) { $mask = "\\$s\share$\ResponderService_*"; # 先读取文件,让NTFS更新LastWriteTime以反映实际情况 gci $mask | gc -TotalCount 1 > $null; $f = (gci $mask |Sort-Object LastWriteTime -Descending |Select-Object -First 1).FullName; # 后续对$f的操作 }
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

