本质是时区和本地化处理差异:资源管理器显示本地时间,而File.GetLastWriteTime()返回Kind为Unspecified的DateTime,ToString()按当前时区解释,易引发转换歧义;推荐优先使用GetLastWriteTimeUtc()获取明确UTC时间。

File.GetLastWriteTime() 返回的时间为什么和资源管理器里看到的不一致?
本质是时区和本地化处理差异。Windows 资源管理器默认显示「本地时间」,而 File.GetLastWriteTime() 返回的是 DateTime 类型,其 Kind 属性通常为 Unspecified,直接 ToString() 会按当前系统时区解释,但若后续参与时区转换(比如调用 ToUniversalTime())就可能偏移。
- 推荐统一用
File.GetLastWriteTimeUtc()—— 它明确返回 UTC 时间,避免隐式转换歧义 - 如果必须显示本地时间,用
File.GetLastWriteTime().ToLocalTime(),而非对 UTC 结果再调ToLocalTime() - 注意 FAT32 文件系统只保留到 2 秒精度,NTFS 是 100 纳秒;实测中修改后立即读取可能因缓存未刷新而拿到旧值,可加
Thread.Sleep(10)或用FileSystemWatcher确认变更已落盘
创建时间(CreationTime)在重命名/移动后会不会变?
会变——但只在跨卷移动时。同一 NTFS 卷内剪切粘贴或重命名,CreationTime 不变;从 C: 剪切到 D:,Windows 实际执行的是「复制 + 删除」,新文件的 CreationTime 就是当前时间。
- 用
File.GetCreationTime()读取前,先确认路径有效性:File.Exists(path)必须为 true,否则抛FileNotFoundException - 某些备份工具或 OneDrive 同步过程会重写文件元数据,导致
CreationTime被覆盖,此时应优先信任LastWriteTime - 若需稳定标识文件生命周期,不要依赖
CreationTime,改用文件内容哈希或自建日志记录首次写入时间
DirectoryInfo 和 FileInfo 哪个更适合批量读取多个文件时间属性?
FileInfo 更轻量、更可控。DirectoryInfo 的 GetFiles() 返回的是未初始化的 FileInfo 对象,只有访问 LastWriteTime 等属性时才触发实际文件系统调用;而 FileInfo 构造函数本身不查磁盘,真正 IO 发生在属性首次访问时。
- 批量场景下,用
new FileInfo(path).LastWriteTimeUtc比DirectoryInfo.GetFiles()[i].LastWriteTimeUtc更清晰,避免误以为GetFiles()已预加载全部属性 - 如果要读取大量文件且只关心时间戳,禁用长路径支持可小幅提速:确保路径不含
\?前缀,否则 .NET 会绕过部分 Win32 优化路径 - 注意
FileInfo不缓存结果——每次访问LastWriteTime都是一次新的系统调用,频繁读取同一文件请自行缓存
遇到“拒绝访问”异常时,如何安全跳过系统保护文件?
像 C:pagefile.sys 或 C:hiberfil.sys 这类文件即使有管理员权限也常被内核锁定,File.GetLastWriteTime() 会直接抛 UnauthorizedAccessException,不能靠 try-catch 吞掉就完事。
- 先用
File.GetAttributes(path)检查是否含FileAttributes.System或FileAttributes.Hidden,再决定是否尝试读取 - 对不确定路径,统一用 try/catch 包裹,并区分异常类型:
FileNotFoundException可静默跳过,UnauthorizedAccessException建议记录警告但不停止流程 - 别用
Process.Start("cmd", "/c dir")这类外部命令绕过——权限问题同样存在,且性能差、不可靠
LastWriteTime 可能出现「倒流」(比如 10:05:00 写入的文件,读出来是 10:04:59)。需要严格时序逻辑时,得结合文件内容校验或外部时间源。


















