如何在Java/Scala中优雅提取Windows NTFS文件的Date属性?
在Java/Scala中读取Windows NTFS文件的「Date」属性
Windows资源管理器「详细信息」视图里的「Date」属性属于Windows Shell定义的System.Date元数据属性,它会根据文件类型自动关联对应的实际时间(比如图片的拍摄日期、Office文档的创建日期等),标准Java IO/NIO API无法直接读取该属性,最简方案是通过JNA调用Windows原生Shell API来实现。
实现步骤
1. 引入JNA依赖
如果用Maven,在pom.xml中添加:
<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.13.0</version> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> <version>5.13.0</version> </dependency>
如果用Gradle:
implementation 'net.java.dev.jna:jna:5.13.0' implementation 'net.java.dev.jna:jna-platform:5.13.0'
2. 编写读取代码
以下是Java示例,Scala版本逻辑完全一致,仅语法调整:
import com.sun.jna.platform.win32.Shell32; import com.sun.jna.platform.win32.ShlObj; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinNT; import com.sun.jna.ptr.PointerByReference; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; public class WindowsDatePropertyReader { public static Date getSystemDateProperty(File file) { WinDef.HWND hwnd = null; PointerByReference pItem = new PointerByReference(); int result = Shell32.INSTANCE.SHCreateItemFromParsingName( file.getAbsolutePath(), null, ShlObj.IID_IShellItem2, pItem ); if (result != 0) { return null; } ShlObj.IShellItem2 shellItem = ShlObj.IShellItem2.Converter.NATIVE.convert(pItem.getValue()); WinPropVariant.VARIANT variant = new WinPropVariant.VARIANT(); try { // 读取System.Date对应的属性键PKEY_Date int propResult = shellItem.GetProperty(WinPropVariant.PKEY_Date, variant); if (propResult == 0 && variant.vt == WinPropVariant.VT_FILETIME) { // 将Windows FILETIME转换为Java Date long fileTime = (long) variant.filetime.dwHighDateTime << 32 | variant.filetime.dwLowDateTime & 0xFFFFFFFFL; return new Date((fileTime / 10000) - 11644473600000L); } } finally { shellItem.Release(); } return null; } public static void main(String[] args) { File file = new File("C:\\example.jpg"); Date date = getSystemDateProperty(file); if (date != null) { System.out.println("Date属性值:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date)); } else { System.out.println("无法读取Date属性"); } } }
注意事项
- 该方法仅在Windows系统下有效,跨平台场景需先做系统判断
- 部分文件可能没有
System.Date属性,需处理返回null的情况 - 需确保程序有足够权限读取文件元数据
内容的提问来源于stack exchange,提问作者Marcin Belicki
相关产品推荐
相关产品推荐

