2013-04-21 9 views
6

Я хочу изменить метаданные метки времени на файлы в Java, используя класс java.nio.Files.Установка/изменение атрибута ctime или атрибута «Изменить время» в файле

Я хотел бы изменить все 3 временные метки Linux/ext4 (последнее изменение, доступ и изменение).

Я могу изменить первые два поля временных меток следующим образом:

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

Однако, я не могу изменить последний изменения: время на файл. Кроме того, это касается того, что нет метки времени изменения, упомянутой в documentation. Самый близкий доступный атрибут - creationTime, который я пробовал без каких-либо успехов.

Любые идеи по изменению метаданных Change: для файла в соответствии с пользовательской меткой времени в Java?

Спасибо!

+0

В терминале Linux для вывода ls отображается последнее измененное время, вы пытались его изменить? –

+0

Да. Я успешно модифицировал последнее модифицированное время, используя первую строку кода выше. – Eitan

ответ

10

Я был в состоянии изменить CTIME с двумя различными способами:

  1. Изменение ядра так, что ctime соответствует mtime
  2. Дать простой (но Hacky) скрипт.

1-й способ: изменение ядра.

Я отредактировал всего несколько строк в 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); 

Вот изменение KERNEL_SRC/fs/attr.c в функции notify_change:

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 в это значение.

2-й метод: простой (но хакерский) сценарий оболочки.

Краткое объяснение: 1) Изменение системного времени к вашей целевой времени 2) выполнить CHMOD на файл, файл CTime в настоящее время отражает целевое время 3) Revert системного времени назад.

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 = $ (date) не (всегда?) получает действительный формат даты для настройки. Использовать: now = $ (date + "% Y-% M-% d% T"). Этот скрипт/метод является опрятным, и он работает для меня. – gaoithe

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