Bestimmen Sie das Erstellungsdatum der Datei in Java

102

Es gibt eine andere ähnliche Frage wie bei StackOverflow ( So erhalten Sie das Erstellungsdatum einer Datei in Java ), aber die Antwort ist nicht wirklich da, da das OP einen anderen Bedarf hatte, der über andere Mechanismen gelöst werden könnte. Ich versuche, eine Liste der Dateien in einem Verzeichnis zu erstellen, die nach Alter sortiert werden kann, weshalb das Erstellungsdatum der Datei erforderlich ist.

Ich habe keine gute Möglichkeit gefunden, dies nach langem Durchsuchen des Webs zu tun. Gibt es einen Mechanismus zum Abrufen von Dateierstellungsdaten?

BTW, derzeit auf einem Windows-System, benötigt dies möglicherweise auch, um auf einem Linux-System zu funktionieren. Ich kann auch nicht garantieren, dass eine Dateinamenskonvention befolgt wird, bei der das Erstellungsdatum / die Erstellungszeit in den Namen eingebettet sind.

Todd
quelle
2
Okay, nach weiteren Diskussionen und Untersuchungen in den Dateisystemen haben wir entschieden, dass die Verwendung der letzten Änderung ausreichend ist, da sie wahrscheinlich zusammen mit dem Erstellungsdatum überprüft worden sein müsste. Beide müssten überprüft werden, um festzustellen, ob eine alte Datei kürzlich geändert wurde und daher noch aktiv ist. Suchen Sie einfach nach der Datei, die am weitesten in der Vergangenheit geändert wurde. Vielen Dank für alle Beiträge. Übrigens würde ich gerne nio verwenden, aber die Linux-Variante hier unterstützt die Dateierstellung sowieso nicht.
Todd

Antworten:

163

Java nio bietet Optionen für den Zugriff auf CreationTime und andere Metadaten, sofern das Dateisystem dies bereitstellt. Überprüfen Sie diesen Link aus

Zum Beispiel (bereitgestellt basierend auf dem Kommentar von @ ydaetskcoR):

Path file = ...;
BasicFileAttributes attr = Files.readAttributes(file, BasicFileAttributes.class);

System.out.println("creationTime: " + attr.creationTime());
System.out.println("lastAccessTime: " + attr.lastAccessTime());
System.out.println("lastModifiedTime: " + attr.lastModifiedTime());
Ringträger
quelle
16
Dies wäre am besten, aber es ist Java 7. Wir verwenden immer noch 6, aber ich werde unsere Upgrade-Optionen untersuchen.
Todd
1
Fantastisch. Genau das brauchte ich.
RestInPeace
7
Verwenden readAttributes(file.toPath(), BasicFileAttributes.class)Sie sonst erhalten Sie:no suitable method found for readAttributes(File,Class<BasicFileAttributes>) method Files.<A>readAttributes(Path,Class<A>,LinkOption...) is not applicable (cannot infer type-variable(s) A (argument mismatch; File cannot be converted to Path))
Hooli
1
@Hooli Keine Sorge, Kumpel! Versuchen Sie dies unter logicbig.com/how-to/java/file-creation-date.html .
Sokrates
1
Das Erstellungsdatum der Datei ist in JDK 8 (zumindest) nicht verfügbar, da statxsyscall in einer neueren Linux-Kernel-Version hinzugefügt wurde.
St.Antario
15

Ich habe dieses Problem mit JDK 7 mit folgendem Code gelöst:

package FileCreationDate;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class Main
{
    public static void main(String[] args) {

        File file = new File("c:\\1.txt");
        Path filePath = file.toPath();

        BasicFileAttributes attributes = null;
        try
        {
            attributes =
                    Files.readAttributes(filePath, BasicFileAttributes.class);
        }
        catch (IOException exception)
        {
            System.out.println("Exception handled when trying to get file " +
                    "attributes: " + exception.getMessage());
        }
        long milliseconds = attributes.creationTime().to(TimeUnit.MILLISECONDS);
        if((milliseconds > Long.MIN_VALUE) && (milliseconds < Long.MAX_VALUE))
        {
            Date creationDate =
                    new Date(attributes.creationTime().to(TimeUnit.MILLISECONDS));

            System.out.println("File " + filePath.toString() + " created " +
                    creationDate.getDate() + "/" +
                    (creationDate.getMonth() + 1) + "/" +
                    (creationDate.getYear() + 1900));
        }
    }
}
Oleksandr Tarasenko
quelle
13

Als Folge dieser Frage - da sie sich speziell auf die Erstellungszeit bezieht und die Erlangung über die neuen nio-Klassen erörtert - scheint es, dass Sie in der Implementierung von JDK7 derzeit kein Glück haben. Nachtrag: Das gleiche Verhalten ist in OpenJDK7.

Auf Unix-Dateisystemen können Sie den Erstellungszeitstempel nicht abrufen. Sie erhalten lediglich eine Kopie der letzten Änderungszeit. So traurig, aber leider wahr. Ich bin mir nicht sicher, warum das so ist, aber der Code macht das speziell, wie das Folgende zeigen wird.

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.*;

public class TestFA {
  static void getAttributes(String pathStr) throws IOException {
    Path p = Paths.get(pathStr);
    BasicFileAttributes view
       = Files.getFileAttributeView(p, BasicFileAttributeView.class)
              .readAttributes();
    System.out.println(view.creationTime()+" is the same as "+view.lastModifiedTime());
  }
  public static void main(String[] args) throws IOException {
    for (String s : args) {
        getAttributes(s);
    }
  }
}
David Nugent
quelle
1
Wissen Sie, wie es für Android geht? BasicFileAttributes ist dort nicht als eingebaute API verfügbar ...
Android-Entwickler
Dies ist in der Tat wahr, selbst ein Aufruf an statfunktioniert nicht. Sofern Sie nicht zufällig einen Kernel höher als 4.11 mit glibc höher als 2.28 und Coreutils höher als 8.31 ausführen, statwird die Geburt der Datei gemeldet . Siehe verwandte Antwort unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4/… Derzeit verwendet das JDK statx syscal nicht.
Brice
12

Dies ist ein grundlegendes Beispiel für das Abrufen des Erstellungsdatums einer Datei Javamithilfe der BasicFileAttributesKlasse:

   Path path = Paths.get("C:\\Users\\jorgesys\\workspaceJava\\myfile.txt");
    BasicFileAttributes attr;
    try {
    attr = Files.readAttributes(path, BasicFileAttributes.class);
    System.out.println("Creation date: " + attr.creationTime());
    //System.out.println("Last access date: " + attr.lastAccessTime());
    //System.out.println("Last modified date: " + attr.lastModifiedTime());
    } catch (IOException e) {
    System.out.println("oops error! " + e.getMessage());
}
Jorgesys
quelle
Personen, die diese Klasse verwenden möchten, sollten beachten, dass der Versand in Java 1.7 gestartet wurde.
JWJ
9

Die API von java.io.Fileunterstützt nur das Abrufen der zuletzt geänderten Zeit. Auch in diesem Bereich ist das Internet sehr leise.

Sofern ich nichts Wichtiges verpasst habe, enthält die Java-Bibliothek (bis zu, aber noch nicht in Java 7 enthalten) diese Funktion nicht. Wenn Sie also verzweifelt danach suchen, besteht eine Lösung darin, C (++) - Code zu schreiben, um Systemroutinen aufzurufen und mit JNI aufzurufen. Der größte Teil dieser Arbeit scheint jedoch bereits in einer Bibliothek namens JNA für Sie erledigt worden zu sein .

Möglicherweise müssen Sie hierfür jedoch noch ein wenig betriebssystemspezifische Codierung in Java vornehmen, da in Windows und Unix / Linux / BSD / OS X wahrscheinlich nicht dieselben Systemaufrufe verfügbar sind.

Carl Smotricz
quelle
2
Ja, Java 7 wäre großartig, da das Nio dies in grundlegenden Attributen zu haben scheint. Ich hätte nie gedacht, dass ich mich darüber beschweren würde, zu früh geboren zu werden! ;)
Todd
6
Der Grund, warum die FileKlasse diese Funktion nicht besitzt, ist, dass die meisten Dateisysteme diese Informationen nicht einmal verfolgen. Und diejenigen, die sich nicht immer einig sind, wann es aktualisiert werden soll.
Syntaktische
@Syntactic: Tatsächlich verfolgen die meisten Dateisysteme diese Informationen . Ausnahmen sind ext <= 3 und Reiser. FAT, NTFS, HFS, ZFS und ext4 unterstützen dies. Es hat sich jedoch nur langsam auf allen Linux-Ebenen sowie in den Bibliotheken und Befehlen verbreitet, um eine universelle Verwendung zu erreichen.
Hippietrail
@Carl Unter Linux erhalte ich bei Verwendung von Java NIO das gleiche Änderungs- und Erstellungsdatum. Ist es das normale Verhalten?
Jayesh Dhandha
@ JayeshDhandha, wenn nichts die Datei nach ihrer Erstellung ändert, würde ich erwarten , dass die Erstellungs- und Änderungszeiten gleich sind. Sie können versuchen, dies zu ändern, indem Sie touchdie Mod-Zeit ändern und dann erneut überprüfen.
Carl Smotricz
9

Auf einem Windows-System können Sie die kostenlose FileTimes- Bibliothek verwenden.

Dies wird in Zukunft mit Java NIO.2 (JDK 7) und dem Paket java.nio.file.attribute einfacher .

Beachten Sie jedoch, dass die meisten Linux-Dateisysteme keine Zeitstempel für die Dateierstellung unterstützen .

Jacek S.
quelle
Gibt es einen anderen Weg für Linux-Maschinen, die die erstellte Zeit nicht unterstützen?
Maverick
Verwenden Sie einfach ein Dateisystem, das Zeitstempel für die Dateierstellung unterstützt. Der verlinkte Wikipedia-Artikel schlägt ext4 vor, was mittlerweile weit verbreitet ist.
Davom
1

in java1.7 + Mit diesem Code können Sie die Erstellungszeit für Dateien ermitteln!

private static LocalDateTime getCreateTime(File file) throws IOException {
        Path path = Paths.get(file.getPath());
        BasicFileAttributeView basicfile = Files.getFileAttributeView(path, BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
        BasicFileAttributes attr = basicfile.readAttributes();
        long date = attr.creationTime().toMillis();
        Instant instant = Instant.ofEpochMilli(date);
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }
zhangxinqiang
quelle
könnten Sie bitte sorgfältig ausarbeiten , warum brauchen wir diese Hektik mit Instant.ofEpochMilli(date). Vielen Dank
Kirill Karmazin