Установка / изменение атрибута ctime или "изменить время" в файле
Я хочу изменить метаданные метки времени на файлах в Java, используя java.nio.Files
класса.
Я хотел бы изменить все 3 временные метки Linux/ext4 (последние изменения, доступ и изменения).
Я могу изменить первые два поля метки времени следующим образом:
Files.setLastModifiedTime(pathToMyFile, myCustomTime);
Files.setAttribute(pathToMyFile, "basic:lastAccessTime", myCustomTime);
однако я не могу изменить последний изменения: время в файле. Кроме того, это касается того, что нет метки времени изменения, упомянутой в документация. Ближайший доступный атрибут creationTime
, которые я пробовал без успеха.
любые идеи о том, как изменить Change:
метаданные для файла в соответствии с пользовательской метки в Java?
спасибо!
2 ответов
я смог изменить ctime с помощью двух разных методов:
- изменение ядра, так что
ctime
соответствуетmtime
- написание простого (но вымышленная) скрипт.
1-й метод: изменение ядра.
Я настроил всего несколько строк в KERNEL_SRC/fs/attr.c
эта модификация обновляет ctime, чтобы соответствовать mtime всякий раз, когда 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
на :
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) это действительно суть решения. The notify_change
функция выполняется после изменения файла, в котором необходимо обновить метаданные времени. Если mtime не был указан, то mtime устанавливается в текущее время. В противном случае, если mtime было установлено определенное значение, мы также устанавливаем ctime и atime на это значение.
2-й метод: простой (но хакерский) сценарий оболочки.
краткое объяснение: 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
sudo date --set="$now"
выполните это следующим образом: ./файл myfile changectime.sh
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 (GetFileTime функция на MSDN) дайте легкий доступ к этому полю. Собственные системные вызовы предоставляют только доступ к меткам времени создания/доступа/изменения, так же как и Java.