fileinfo能读creationtime、lastwritetime、length、isreadonly等基础属性,但不能读作者、标题、相机型号、文件版本等shell属性或exif元数据,需用fileversioninfo、shell32或metadataextractor等替代方案。

FileInfo能读哪些文件属性,哪些不能读
FileInfo 是 C# 中最直接获取基础文件属性的类,但它只暴露操作系统原生支持、且 .NET 封装明确的字段。比如 CreationTime、LastWriteTime、Length、IsReadOnly 都可以直接访问;但像作者、标题、相机型号这类 Windows 资源管理器里看到的“详细信息”标签页内容,FileInfo 完全不提供——这些属于 NTFS 替换数据流(ADS)或 Shell 属性,得用 Shell32 或第三方库(如 MetadataExtractor)。
常见误判是以为 FileInfo 能读取“文件版本”或“产品名称”,其实它连 VersionInfo 都没有。需要这些时,得用 FileVersionInfo.GetVersionInfo() 单独查。
用 FileInfo 读创建时间、大小、只读状态的正确写法
实例化 FileInfo 后,属性是即时读取的(不是缓存值),所以要注意路径是否存在、权限是否足够。如果文件被其他进程独占锁定,某些属性(尤其是时间戳)可能抛 UnauthorizedAccessException 或返回默认值(如 DateTime.MinValue)。
FileInfo fi = new FileInfo(@"C:\test\report.pdf");- 检查存在性再读:
if (fi.Exists) { Console.WriteLine(fi.CreationTime); } -
Length返回的是long类型字节数,别直接转int,大文件会溢出 -
IsReadOnly只反映文件系统级别的只读标志,和 Windows 的“隐藏只读”UI 勾选一致,但不等同于“不可写”(比如 NTFS 权限可能更严)
为什么有时 CreationTime 和 LastWriteTime 看起来“不准”
Windows 默认启用“最后访问时间更新”,但这个功能在 NTFS 上是禁用的(从 WinVista 起默认关闭),所以 LastAccessTime 经常是旧值甚至不变。而 CreationTime 并非“文件诞生时间”——它是该文件在当前路径下首次被创建的时间;如果文件是从别处复制过来的,CreationTime 就是复制时刻,不是原始创建时刻;如果是剪切(move),则保留原 CreationTime。
更麻烦的是:某些备份/同步工具(如 OneDrive、rsync)会重置时间戳;U 盘或网络共享挂载点也可能因 FAT32 不支持毫秒级精度,导致时间被截断到 2 秒粒度。
- 不要依赖
CreationTime做业务逻辑的时间判定(比如“24 小时内生成”) - 比较时间建议统一用
LastWriteTime,它受用户/程序显式修改影响更可控 - 跨平台注意:Linux/macOS 没有
CreationTime概念,.NET Core 6+ 在非 Windows 上返回DateTime.MinValue
只读属性设置失败的典型原因
FileInfo.IsReadOnly = true 看似简单,但实际调用的是底层 SetAttributes,失败原因很具体:
- 目标路径是只读目录(父文件夹权限锁死),即使文件本身可写,也会失败
- 文件正被另一个进程以
FileShare.None打开(比如记事本未保存就关掉,有时残留句柄) - 运行程序没管理员权限,而文件在
Program Files或系统目录下 - NTFS 权限中,“写属性”权限被显式拒绝(比“只读”标志更高优先级)
安全做法是捕获 UnauthorizedAccessException 和 IOException,并提示用户检查权限或关闭占用程序,而不是静默忽略。
真正难处理的是那些元数据藏在资源分支或 EXIF 里的场景——这时候 FileInfo 就只是个起点,别指望它能覆盖全部需求。










