从Java获取具有毫秒分辨率的文件mtime
当我使用从Java获取具有毫秒分辨率的文件mtime,java,file,last-modified,Java,File,Last Modified,当我使用Files.getLastModifiedTime从Java读取文件的mtime时,返回值被截断为整秒。我知道这可以在其他系统上获得毫秒分辨率的MTIME,那么我的有什么不同呢 以下是编译并运行的完整独立测试: import java.nio.file.attribute.FileTime; import java.nio.file.Files; import java.nio.file.Paths; public class Test { public static void ma
Files.getLastModifiedTime
从Java读取文件的mtime
时,返回值被截断为整秒。我知道这可以在其他系统上获得毫秒分辨率的MTIME,那么我的有什么不同呢
以下是编译并运行的完整独立测试:
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。我尝试了openjdk 1.7和Oracle jdk 1.8。您可以使用简单的日期格式来显示时间为毫秒:
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()));
可以使用简单的日期格式显示时间为毫秒:
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()));
我查看了源代码: 在Java 7的情况下,该方法以1秒的精度给出最后修改的时间戳:
但在这两种情况下,代码似乎都没有提供一种以不同精度获取时间戳的方法。我查看了源代码: 在Java 7的情况下,该方法以1秒的精度给出最后修改的时间戳:
但是在这两种情况下,代码似乎都没有提供以不同精度获取时间戳的方法。在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构建没有设置它,因此时间戳的纳秒部分不可用,并且保持为零。在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构建没有设置它,因此时间戳的纳秒部分不可用并保持为零。在Java 9中似乎是固定的
- Oracle jdk 9.0.4-
提供毫秒分辨率文件。getLastModifiedTime
- Oracle jdk 1.8.162-
提供第二种解决方案文件。getLastModifiedTime
- Oracle jdk 9.0.4-
提供毫秒分辨率文件。getLastModifiedTime
- Oracle jdk 1.8.162-
提供第二种解决方案文件。getLastModifiedTime
time.toMillis
返回的值已被截断为整秒分辨率(即始终以三个零结尾)。这就是问题所在。这似乎很奇怪,因为当我在我的计算机上尝试它时,我得到了毫秒分辨率。我知道它对其他人有效(我编辑了这个问题以澄清这一点),但它在这里不起作用,我正试图找出原因。你误解了。time.toMillis
返回的值已被截断为整秒分辨率(即始终以三个零结尾)。这就是问题所在。这似乎很奇怪,因为当我在我的计算机上尝试它时,我确实获得了毫秒分辨率。我知道它对其他人有效(我编辑了这个问题以澄清这一点),但它在这里不起作用,我正试图找出原因。似乎有关联。我能够在Ubuntu上重现Oracle Java 8的问题。当我使用调试器查看UnixFileAttributes.st_mtime
时,它已经在几秒钟内完成了。本土方面有些问题。而且,即使在Java8(oracle构建,而不是openjdk)中使用,我也无法获得millis。当你运行Java8时,你真的能得到毫秒吗?@izstas宾果!我也在ubuntu上。现在我们只需要知道为什么Ubuntu版本(以及Oracle版本!)没有设置POSIX2008的兼容性。其他OSs或发行版的版本设置了它吗?这些代码是为哪些人运行的?如果你把这个变成一个答案,我会接受的,谢谢!目前的UbuntuJDK8确实提供了微秒级的精度。但是他们可以将其精确到纳秒级,因为评论中的那一刻“如果FileTime被更新为定义from(secs,nsecs)方法,我们可以重新访问它。”。从1.8开始,FileTime定义了一个from(Instant)方法。但除非文件系统以高精度存储时间戳,否则这一切都没有意义。我看到的消息来源说,时间戳精度在不同的文件系统中是高度可变的。(然后考虑时钟精度)似乎是相关的。我能够在Ubuntu上重现Oracle Java 8的问题。当我使用调试器查看UnixFileAttributes.st_mtime
时,它已经在几秒钟内完成了。本土方面有些问题。而且,即使在Java8(oracle构建,而不是openjdk)中使用,我也无法获得millis。当你运行Java8时,你真的能得到毫秒吗?@izstas宾果!我也在ubuntu上。现在我们只需要知道为什么Ubuntu版本(以及Oracle版本!)没有设置POSIX2008的兼容性。其他OSs或发行版的版本设置了它吗?这些代码是为哪些人运行的?如果你把这个变成一个答案,我会接受的,谢谢!目前的UbuntuJDK8确实提供了微秒级的精度。但是他们可以将其精确到纳秒级,因为评论中的那一刻“如果FileTime被更新为定义from(secs,nsecs)方法,我们可以重新访问它。”。从1.8开始,FileTime定义了一个from(Instant)方法。但除非文件系统以高精度存储时间戳,否则这一切都没有意义。我看到的消息来源说,时间戳精度在不同的文件系统中是高度可变的。如果有人感兴趣的话,这个bug就在这里注册:如果有人感兴趣的话,这个bug在这里注册:也固定在Debian的1.80y229中,也固定在Debian的1.80y229中。