2013-04-21 119 views
6

我希望使用java.nio.Files類更改Java文件中的時間戳記元數據。設置/更改文件的ctime或「更改時間」屬性

我想更改所有3個Linux/ext4時間戳(上次修改,訪問和更改)。

我能夠改變前兩個時間戳字段如下:

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

但是,我無法改變最後變化:時間上的文件。另外,關於documentation中提到的沒有更改時間戳。最接近的可用屬性是creationTime,我嘗試過沒有任何成功。

有關如何根據Java中的自定義時間戳修改文件的Change:元數據的任何想法?

謝謝!

+0

在Linux終端中,對於ls輸出,它顯示上次修改時間,您是否嘗試修改它? – 2013-04-21 01:52:17

+0

是的。我使用上面的第一行代碼成功修改了上次修改的時間。 – Eitan 2013-04-21 07:41:17

回答

10

我能夠用兩種不同的方法來修改的ctime:

  1. 改變內核,使ctime匹配mtime
  2. 編寫一個簡單的(但哈克)shell腳本。

第一種方法:更改內核。

我調整了幾行KERNEL_SRC/fs/attr.c此修改更新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權限的文件。確保您在使用該腳本之前根據需要修改此腳本。

+0

需要更改腳本。現在= $(日期)不會(總是)獲取有效的日期格式進行設置。使用:now = $(日期+「%Y-%M-%d%T」)。那個腳本/方法很整潔,對我很有用。 – gaoithe 2016-05-25 10:10:32

2

適應this answer到您的情況:

// 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操作系統(男子觸摸)也不支持Windows(GetFileTime功能上MSDN)可以輕鬆訪問此字段。本地系統調用只能訪問創建/訪問/修改時間戳,Java也是如此。

+0

有沒有其他方法可以讓我保持磁盤安裝? – Eitan 2013-04-21 07:42:51