从Java获取毫秒分辨率的文件mtime

yizd12fk  于 2022-12-28  发布在  Java
关注(0)|答案(5)|浏览(139)

当我使用Files.getLastModifiedTime从Java读取文件的mtime时,返回值被截断为整秒。我知道这在其他系统上可以获得毫秒级分辨率的mtimes,那么我的系统会有什么不同呢?
下面是一个完整的独立测试,该测试将编译并运行:

import java.nio.file.attribute.FileTime;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Test {
  public static void main(String[] args) throws java.io.IOException {
    FileTime timestamp = Files.getLastModifiedTime(Paths.get("/tmp/test"));
    System.out.println(timestamp.toMillis());
  }
}

输出是(使用我的特定测试文件)1405602038000,而ls显示:

$ ls --full-time /tmp/test                                                                                                                                                                                                    
-rw-rw-r-- 1 daniel daniel 0 2014-07-17 16:00:38.413008992 +0300 /tmp/test

我希望Java输出为1405602038413
我在Linux上运行ext4,我尝试了openjdk1.7和Oracle jdk1.8。

csga3l58

csga3l581#

this commit在Java 8中添加了在 *nix系统上以更高精度获取文件时间戳的功能,但在本机端,它需要符合POSIX 2008:

#if (_POSIX_C_SOURCE >= 200809L) || defined(__solaris__)
    (*env)->SetLongField(env, attrs, attrs_st_atime_nsec, (jlong)buf->st_atim.tv_nsec);
    (*env)->SetLongField(env, attrs, attrs_st_mtime_nsec, (jlong)buf->st_mtim.tv_nsec);
    (*env)->SetLongField(env, attrs, attrs_st_ctime_nsec, (jlong)buf->st_ctim.tv_nsec);
#endif

显然,您使用的Java构建版本没有设置它,因此时间戳的纳秒部分不可用,保持为零。

j8yoct9x

j8yoct9x2#

我看了源代码:
在Java 7的情况下,该方法给出了上次修改的时间戳,精度为1秒:

  • http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/nio/fs/UnixFileAttributes.java#UnixFileAttributes.lastModifiedTime%28%29

在Java 8的情况下,它 * 看起来 * 应该给予微秒精度:

  • http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/sun/nio/fs/UnixFileAttributes.java#UnixFileAttributes.lastModifiedTime%28%29

但是在这两种情况下,代码似乎都没有提供获取不同精度的时间戳的方法。

ia2d9nvy

ia2d9nvy3#

它似乎在java 9中得到了修复

  • Oracle jdk 9.0.4 -Files.getLastModifiedTime提供毫秒级分辨率
  • Oracle jdk 1.8.162 -Files.getLastModifiedTime提供了第二种解决方案
7vhp5slm

7vhp5slm4#

您可以使用toInstant().getNano()访问纳秒

BasicFileAttributes attr = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
FileTime ts = attr.lastModifiedTime();
System.out.println("Nano: " + ts.toInstant().getNano());

产量:

Nano: 412413961

# Actual ls ouput:
-rw-r--r-- 1 jotschi jotschi 822 2022-12-25 18:33:12.412413961 +0100 pom.xml
xuo3flqw

xuo3flqw5#

可以使用简单的日期格式以毫秒为单位显示时间:

java.nio.file.attribute.FileTime time = java.nio.file.Files.getLastModifiedTime(java.nio.file.Paths.get("/tmp/test"))
java.text.SimpleDateFormat dateformat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
System.out.println(dateformat.format(time.toMillis()));

相关问题