2013-04-21 8 views
6

Chcę zmienić metadane znacznika czasu dla plików w Javie przy użyciu klasy java.nio.Files.Ustawianie/zmiana atrybutu ctime lub "Change time" w pliku

Chciałbym zmienić wszystkie 3 znaczniki czasu Linux/ext4 (ostatnia modyfikacja, dostęp i zmiana).

jestem w stanie zmienić pierwsze dwa pola datownika następująco:

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

Jednak jestem w stanie zmodyfikować ostatni Zmiana czas na pliku. Ponadto chodzi o to, że nie ma znacznika czasu zmiany wymienionego w documentation. Najbliższym dostępnym atrybutem jest creationTime, którego próbowałem bez żadnego sukcesu.

Jakieś pomysły dotyczące modyfikowania metadanych pliku Change: według niestandardowego znacznika czasu w języku Java?

Dziękujemy!

+0

W terminalu linuksowym, dla wyjścia ls, pokazuje czas ostatniej modyfikacji, czy próbowałeś to zmienić? –

+0

Tak. Udało mi się zmodyfikować czas ostatniej modyfikacji za pomocą pierwszego wiersza kodu powyżej. – Eitan

Odpowiedz

10

udało mi się zmodyfikować ctime z dwóch różnych metod:

  1. Zmiana jądra tak, że ctime dopasowuje mtime
  2. pisania prostych (ale hacky) skrypt.

Pierwsza metoda: zmiana jądra.

Poprawiłem tylko kilka wierszy w KERNEL_SRC/fs/attr.c Ta modyfikacja aktualizuje ctime, aby dopasować do mtime, gdy mtime jest "jawnie zdefiniowane".

Istnieje wiele sposobów na "wyraźnie definiują" The mtime, na przykład:

W systemie Linux:

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

W Javie (używając Java 6 lub 7 i prawdopodobnie innych):

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

Oto zmiana KERNEL_SRC/fs/attr.c w funkcji 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) Ten wiersz, odkomentowany, zaktualizowałby ctime do bieżącego czasu zegara po zmianie pliku. Nie chcemy tego, ponieważ chcemy sami ustawić ctime. W związku z tym skomentowaliśmy tę linię. (To nie jest obowiązkowe)

(2) To naprawdę jest sedno rozwiązania.Funkcja notify_change jest wykonywana po zmianie pliku, w którym należy zaktualizować metadane czasu. Jeśli nie podano mtime, to mtime jest ustawione na bieżący czas. Inaczej, jeśli czas został ustawiony na konkretną wartość, ustawimy także ctime i atime na tę wartość.

Druga metoda: prosty (ale hacki) skrypt powłoki.

Krótkie wyjaśnienie: 1) Zmiana czasu systemowego do czasu docelowego 2) Wykonaj chmod na plik, plik ctime teraz odzwierciedla czas docelowy 3) cofnąć czas systemowy powrotem.

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" 

Run to w następujący sposób: ./changectime.sh MOJPLIK

ctime pliku będzie odzwierciedlać czas w pliku.

Oczywiście, prawdopodobnie nie chcesz pliku z 777 uprawnieniami. Upewnij się, że modyfikujesz ten skrypt do swoich potrzeb, zanim go użyjesz.

+0

Konieczność zmiany skryptu. teraz = $ (data) nie (zawsze?) otrzymuje poprawny format daty do ustawienia. Użyj: teraz = $ (data + "% Y-% M-% d% T"). Ten skrypt/metoda jest zadowalająca i działa dla mnie. – gaoithe

2

Adaptacja this answer do sprawy:

// 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"); 

wątpię widzimy wygodny sposób w standardzie Java API, aby to zrobić, ponieważ ani Linux (mężczyzna dotykowy), ani Windows (GetFileTime funkcji na MSDN) dają łatwy dostęp do tego pola. Natywne wywołania systemowe dają tylko dostęp do znaczników czasu tworzenia/dostępu/modyfikacji, tak samo jak Java.

+0

Czy istnieje alternatywny sposób, który pozwala mi utrzymać dysk zamontowany? – Eitan