设置/更改文件上的ctime或“更改时间”属性

我希望使用java.nio.Files类更改Java文件中的时间戳记元数据。

我想更改所有3个Linux / ext4时间戳(最后修改,访问和更改)。

我能够更改前两个时间戳字段,如下所示:

 Files.setLastModifiedTime(pathToMyFile, myCustomTime); Files.setAttribute(pathToMyFile, "basic:lastAccessTime", myCustomTime); 

但是,我无法修改文件上的最后一个更改:时间。 另外,关于文档中提到的没有更改时间戳的问题。 最接近的可用属性是creationTime ,我尝试没有任何成功。

有关如何根据Java中的自定义时间戳修改文件的Change:元数据的任何想法?

谢谢!

我能够用两种不同的方法修改ctime:

  1. 更改内核,使ctimemtime匹配
  2. 编写一个简单的(但是哈克)shell脚本。

第一种方法:更改内核。

我在KERNEL_SRC/fs/attr.c调整了几行。只要mtime是“明确定义的”,此修改就更新ctime以匹配mtime。

有很多方法可以“明确”定义mtime,例如:

在Linux中:

 touch -m --date="Wed Jun 12 14:00:00 IDT 2013" filename 

在Java中(使用Java 6或7,推测是其他):

 long newModificationTime = TIME_IN_MILLIS_SINCE_EPOCH; File myFile = new File(myPath); newmeta.setLastModified(newModificationTime); 

以下是在notify_change函数中对KERNEL_SRC/fs/attr.c的更改:

  now = current_fs_time(inode->i_sb); //attr->ia_ctime = now; (1) Comment this out if (!(ia_valid & ATTR_ATIME_SET)) attr->ia_atime = now; if (!(ia_valid & ATTR_MTIME_SET)) { attr->ia_mtime = now; } else { //mtime is modified to a specific time. (2) Add these lines attr->ia_ctime = attr->ia_mtime; //Sets the ctime attr->ia_atime = attr->ia_mtime; //Sets the atime (optional) } 

(1)这条线未注释,在更改文件时会将ctime更新为当前时钟时间。 我们不想要这个,因为我们想自己设定ctime。 因此,我们评论这条线。 (这不是强制性的)

(2)这确实是解决方案的关键。 notify_change函数在更改文件后执行,其中时间元数据需要更新。 如果没有指定mtime,则将mtime设置为当前时间。 否则,如果mtime被设置为特定的值,我们也将ctime和atime设置为该值。

第二种方法:简单(但哈克)shell脚本。

简要说明:1)将系统时间更改为目标时间2)对文件执行chmod,文件ctime现在反映目标时间3)将系统时间还原回去。

changectime.sh

 #!/bin/sh now=$(date) echo $now sudo date --set="Sat May 11 06:00:00 IDT 2013" chmod 777 $1 sudo date --set="$now" 

运行如下:./changectime.sh MYFILE

文件的ctime现在将反映文件中的时间。

当然,你可能不想拥有777权限的文件。 确保您在使用之前修改此脚本以满足您的需求。

根据你的情况调整这个答案 :

 // Warning: Disk must be unmounted before this operation String disk = "/dev/sda1"; // Update ctime Runtime.getRuntime().exec("debugfs -w -R 'set_inode_field "+pathToMyFile+" ctime "+myCustomTime+"' "+disk); // Drop vm cache so ctime update is reflected Runtime.getRuntime().exec("echo 2 > /proc/sys/vm/drop_caches"); 

我怀疑我们会在标准Java API中看到一个方便的方法,因为Linux(man touch )和Windows(MSDN上的GetFileTime函数)都不能轻松访问此字段。 本地系统调用只能访问创建/访问/修改时间戳,Java也是如此。