java 中的文件上次访问时间和上次修改时间?
File last access time and last modified time in java?
在我的应用程序中,我使用以下方法读取文件,
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 中上次访问时间和上次修改时间的实际含义吗?
首先,让我们关注一下这些东西的含义。
Access - 最后一次读取文件的时间,即最后一次访问文件数据的时间。
Modify - 最后一次修改文件(内容已被修改),即最后一次修改文件数据的时间。
Change - 文件的元数据最后一次更改(例如权限),即文件状态最后一次更改的时间。
编辑。
访问时间 IS 正在更改。 我建议你使用 Thread.sleep(100)
之类的,然后看看这个问题是否仍然存在。
如果是这样,罪魁祸首将是 OS 你是 运行 因为 Java 只是从文件系统读取。 @Serge Ballesta 的评论应该让您了解 Windows NTFS 出于性能原因可以选择禁用将对文件属性所做的所有更改写回硬盘驱动器。实际上还有更多。
来自 [docs],
NTFS delays updates to the last access time for a file by up to one hour after the last access. NTFS also permits last access time updates to be disabled. Last access time is not updated on NTFS volumes by default.
以下是 运行 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;
如果您查看 api,您会发现这个。
If the file system implementation does not support a time stamp
to indicate the time of last access then this method returns
an implementation specific default value, typically the last-modified-time
or a FileTime
representing the epoch (1970-01-01T00:00:00Z).
看起来 "problem" 与您的文件系统和操作系统有关。我认为您的代码没有任何问题。
例如,在 Vista 和 Windows 7 中默认启用了一个 windows operating system, the NtfsDisableLastAccessUpdate 选项,但您可以使用以下命令行禁用它:
fsutil behavior set disablelastaccess 0
正如我在对您的问题的评论中所说,我能够在 Windows 中在真实机器中解决此问题,但不能在虚拟机器中解决。如果您仍在为这个问题而苦苦挣扎,那么在执行任何操作之前发出此命令以查看注册表发生了什么:
fsutil behavior query disablelastaccess
最后一点,我不必重新启动 windows 或 Intellij(我 运行 我的测试)。结果是立竿见影的,我可以看到对于值 1,最后一次访问的时间戳没有改变,而对于值 0,它确实改变了。
在我的应用程序中,我使用以下方法读取文件,
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 中上次访问时间和上次修改时间的实际含义吗?
首先,让我们关注一下这些东西的含义。
Access - 最后一次读取文件的时间,即最后一次访问文件数据的时间。
Modify - 最后一次修改文件(内容已被修改),即最后一次修改文件数据的时间。
Change - 文件的元数据最后一次更改(例如权限),即文件状态最后一次更改的时间。
编辑。
访问时间 IS 正在更改。 我建议你使用 Thread.sleep(100)
之类的,然后看看这个问题是否仍然存在。
如果是这样,罪魁祸首将是 OS 你是 运行 因为 Java 只是从文件系统读取。 @Serge Ballesta 的评论应该让您了解 Windows NTFS 出于性能原因可以选择禁用将对文件属性所做的所有更改写回硬盘驱动器。实际上还有更多。
来自 [docs],
NTFS delays updates to the last access time for a file by up to one hour after the last access. NTFS also permits last access time updates to be disabled. Last access time is not updated on NTFS volumes by default.
以下是 运行 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;
如果您查看 api,您会发现这个。
If the file system implementation does not support a time stamp to indicate the time of last access then this method returns an implementation specific default value, typically the
last-modified-time
or aFileTime
representing the epoch (1970-01-01T00:00:00Z).
看起来 "problem" 与您的文件系统和操作系统有关。我认为您的代码没有任何问题。
例如,在 Vista 和 Windows 7 中默认启用了一个 windows operating system, the NtfsDisableLastAccessUpdate 选项,但您可以使用以下命令行禁用它:
fsutil behavior set disablelastaccess 0
正如我在对您的问题的评论中所说,我能够在 Windows 中在真实机器中解决此问题,但不能在虚拟机器中解决。如果您仍在为这个问题而苦苦挣扎,那么在执行任何操作之前发出此命令以查看注册表发生了什么:
fsutil behavior query disablelastaccess
最后一点,我不必重新启动 windows 或 Intellij(我 运行 我的测试)。结果是立竿见影的,我可以看到对于值 1,最后一次访问的时间戳没有改变,而对于值 0,它确实改变了。