在java中记录上次访问时间和上次修改时间?

时间:2016-05-11 07:22:32

标签: java nio java-io

在我的应用程序中,我使用以下方法读取文件,

public void readFIleData(String path) {
    BufferedReader br = null;
    try {
        String sCurrentLine;
        br = new BufferedReader(new FileReader(path));
        while ((sCurrentLine = br.readLine()) != null) {
            System.out.println("Data : "+sCurrentLine);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (br != null)br.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

我还使用以下方法获取文件的上次访问时间和上次修改时间

public void getFIleInfo(String path) {
    Path file = Paths.get(path);
    try {
        BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
        FileTime accessTime = attrs.lastAccessTime();
        System.out.println("accessTime : "+accessTime.toMillis());
        FileTime modifiedTime = attrs.lastModifiedTime();
        System.out.println("modifiedTime : "+modifiedTime.toMillis());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

我按照以下顺序运行了上述方法,

1-> getFIleInfo()
2-> readFIleData()
3-> getFIleInfo()

我得到了以下输出,

accessTime : 1462943491685
modifiedTime : 1462943925846
Data : erteuyuittdgfdfghjkhw5643rtrr66664fdghf
accessTime : 1462943491685
modifiedTime : 1462943925846

以下是字符串格式的输出时间,

accessTime : 2016-05-11T05:11:31.685881Z
modifiedTime : 2016-05-11T07:39:28.237884Z
Data : erteuyuittdgfdfghjkhw5643rtrr66LE229F1HBQ664fdghf
accessTime : 2016-05-11T05:11:31.685881Z
modifiedTime : 2016-05-11T07:39:28.237884Z

我对此输出有疑问,因为访问时间与读取文件数据前相同。有人可以向我解释一下java上次访问时间和上次修改时间的实际意义吗?

2 个答案:

答案 0 :(得分:2)

首先,让我们关注这些事情的含义。

访问 - 上次读取文件的时间,即上次访问文件数据的时间。

修改 - 上次修改文件(内容已被修改),即上次修改文件数据的时间。

更改 - 上次更改文件的元数据(例如权限),即上次更改文件状态的时间。

修改即可。 访问时间 IS 正在发生变化。 我建议您使用Thread.sleep(100)或其他内容,然后查看此问题是否仍然存在。 如果是这样,罪魁祸首就必须是您正在运行的操作系统,因为Java只是从文件系统中读取。 @Serge Ballesta的注释应该让我们了解Windows NTFS有一个选项,可以出于性能原因禁止将对文件属性所做的每个更改写回硬盘驱动器。实际上还有更多。

来自[docs],

  

NTFS在上次访问后最多延迟一小时将更新延迟到文件的上次访问时间。 NTFS还允许禁用上次访问时间更新。默认情况下,上次访问时间不会在NTFS卷上更新。

以下是在mac os x上运行脚本的一些数据。

calling getFileInfo() at: 11.4.2016 3:13:08:738
    accessTime : 11.4.2016 3:12:53:0
    modifiedTime : 29.10.2015 1:49:14:0
--------------------
sleeping for 100ms
--------------------
calling readFIleData() at: 11.4.2016 3:13:08:873
--------------------
sleeping for 100ms
--------------------
re-calling getFileInfo() at: 11.4.2016 3:13:08:977
    accessTime : 11.4.2016 3:13:08:0 <---- READING FILE CHANGES ACCESS TIME
    modifiedTime : 29.10.2015 1:49:14:0
--------------------
sleeping for 100ms
--------------------
re-calling getFileInfo() at: 11.4.2016 3:13:09:81
    accessTime : 11.4.2016 3:13:08:0 <---- READING FILE ATTRIBUTES DOES NOT CHANGE ACCESS TIME
    modifiedTime : 29.10.2015 1:49:14:0 

<小时/> 为了提高清晰度,您可以将毫秒数转换为更具可读性的内容。以下代码片段将详细说明。

long accessTimeSinceEpoch = Files.readAttributes(file, BasicFileAttributes.class).lastAccessTime().toMillis();

Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(accessTimeSinceEpoch);

int mYear = calendar.get(Calendar.YEAR);
int mMonth = calendar.get(Calendar.MONTH);
int mDay = calendar.get(Calendar.DAY_OF_MONTH);

int mHour = calendar.get(Calendar.HOUR);
int mMin = calendar.get(Calendar.MINUTE);
int mSec = calendar.get(Calendar.SECOND);
int mMilisec = calendar.get(Calendar.MILLISECOND);
String st = mDay + "." + mMonth + "." + mYear + " " + mHour + ":" + mMin + ":" + mSec + ":" + mMilisec;

答案 1 :(得分:0)

如果你看看api,你有这个。

  

如果文件系统实现不支持时间戳       指示上次访问的时间,然后此方法返回        特定于实现的默认值,通常为last-modified-timeFileTime         代表时代(1970-01-01T00:00:00Z)。

看起来非常像“问题”与您的文件系统和操作系统有关。我不认为你的代码有任何错误。

例如,对于windows operating system,默认情况下在Vista和Windows 7中启用了NtfsDisableLastAccessUpdate选项,但您可以使用以下命令行将其禁用:

fsutil behavior set disablelastaccess 0

正如我在你的问题的评论中所说,我能够在真实机器中解决Windows中的这个问题,但不能在虚拟机器中解决。如果你仍在努力解决这个问题,那么在任何事情之前发出这个命令,看看注册表是怎么回事:

fsutil behavior query disablelastaccess 

最后一点,我没有重新启动Windows或Intellij(我运行我的测试)。结果是立即的,我可以看到,对于值1,上次访问的时间戳不会改变,而值0则不会改变。