Déterminer la date de création du fichier en Java

102

Il y a une autre question similaire à la mienne sur StackOverflow ( Comment obtenir la date de création d'un fichier en Java ), mais la réponse n'est pas vraiment là car l'OP avait un besoin différent qui pourrait être résolu via d'autres mécanismes. J'essaie de créer une liste des fichiers dans un répertoire qui peut être trié par âge, d'où la nécessité de la date de création du fichier.

Je n'ai trouvé aucun bon moyen de le faire après de nombreuses recherches sur le Web. Existe-t-il un mécanisme pour obtenir les dates de création des fichiers?

BTW, actuellement sur un système Windows, peut également en avoir besoin pour fonctionner sur un système Linux. En outre, je ne peux pas garantir qu'une convention de dénomination de fichier serait suivie lorsque la date / heure de création est intégrée dans le nom.

Todd
la source
2
D'accord, après plus de discussions et d'enquêtes sur les systèmes de fichiers, nous avons décidé que l'utilisation de la dernière modification était suffisante car elle aurait probablement dû être vérifiée avec la date de création. Les deux devraient être vérifiés pour déterminer si un ancien fichier a été récemment modifié et donc toujours actif. Donc, vérifiez simplement le fichier modifié le plus loin dans le passé. Merci pour toute la contribution. BTW, j'aimerais utiliser nio, mais la saveur Linux ici ne prend pas en charge la création de fichiers de toute façon.
Todd

Réponses:

163

Java nio propose des options pour accéder à creationTime et à d'autres métadonnées tant que le système de fichiers les fournit. Vérifiez ce lien sur

Par exemple (fourni sur la base du commentaire de @ 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());
porteur de l'anneau
la source
16
Ce serait mieux, mais c'est Java 7. Nous utilisons toujours 6, mais je vais étudier nos options de mise à niveau.
Todd
1
Fantastique. J'avais exactement besoin.
RestInPeace
7
utilisez readAttributes(file.toPath(), BasicFileAttributes.class)autrement vous obtenez: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 Pas de soucis, mon pote! Essayez ce logicbig.com/how-to/java/file-creation-date.html .
Socrates
1
La date de création du fichier n'est pas disponible sur JDK 8 (au moins) depuis que statxsyscall a été ajouté dans la nouvelle version du noyau Linux.
St.Antario
15

J'ai résolu ce problème en utilisant JDK 7 avec ce code:

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
la source
13

Pour faire suite à cette question - puisqu'elle concerne spécifiquement le moment de la création et discute de son obtention via les nouvelles classes nio - il semble qu'en ce moment, dans l'implémentation de JDK7, vous n'avez pas de chance. Addendum: même comportement dans OpenJDK7.

Sur les systèmes de fichiers Unix, vous ne pouvez pas récupérer l'horodatage de création, vous obtenez simplement une copie de l'heure de la dernière modification. Si triste, mais malheureusement vrai. Je ne sais pas pourquoi, mais le code le fait spécifiquement, comme le démontrera ce qui suit.

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
la source
1
Savez-vous comment faire pour Android? BasicFileAttributes n'est pas disponible en tant qu'API intégrée là-bas ...
Développeur Android
C'est en effet vrai, même un appel statne fonctionne pas. À moins que vous n'exécutiez un noyau supérieur à 4.11 avec glibc supérieur à 2.28 et coreutils supérieur à 8.31, alors vous statrapporterez la naissance du fichier. Voir la réponse associée unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4/… Actuellement, le JDK n'utilise pas statx syscal.
Brice
12

Voici un exemple de base de la façon d'obtenir la date de création d'un fichier dans Java, en utilisant la BasicFileAttributesclasse:

   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
la source
Les personnes souhaitant utiliser cette classe doivent noter qu'elle a commencé à être livrée avec Java 1.7.
jwj
9

L'API de java.io.Filene prend en charge que la dernière heure de modification . Et Internet est également très silencieux sur ce sujet.

Sauf si j'ai manqué quelque chose d'important, la bibliothèque Java telle quelle (jusqu'à Java 7, mais pas encore incluse) n'inclut pas cette fonctionnalité. Donc, si vous étiez désespéré pour cela, une solution serait d'écrire du code C (++) pour appeler les routines système et de l'appeler en utilisant JNI. Cependant, la plupart de ce travail semble déjà être fait pour vous dans une bibliothèque appelée JNA .

Vous devrez peut-être encore faire un peu de codage spécifique au système d'exploitation en Java pour cela, car vous ne trouverez probablement pas les mêmes appels système disponibles sous Windows et Unix / Linux / BSD / OS X.

Carl Smotricz
la source
2
Ouais, Java 7 serait génial car le nio semble avoir cela dans les attributs de base. Je n'aurais jamais pensé que je me plaindrais d'être né trop tôt! ;)
Todd
6
La raison pour laquelle la Fileclasse n'a pas cette capacité est que la plupart des systèmes de fichiers ne suivent même pas ces informations. Et ceux qui ne s'entendent pas toujours sur le moment où il doit être mis à jour.
Syntactique
@Syntactic: En fait, la plupart des systèmes de fichiers suivent ces informations . Les exceptions incluent ext <= 3 et Reiser. FAT, NTFS, HFS, ZFS et ext4 le prennent en charge. Mais il a été lent à se propager à travers toutes les couches de Linux et les bibliothèques et commandes pour le rendre universellement utilisé.
hippietrail
@Carl Sous Linux, j'obtiens la même date de modification et de création lorsque j'utilise Java NIO. Est-ce le comportement normal?
Jayesh Dhandha le
@JayeshDhandha, si rien ne modifie le fichier après sa création, je m'attendrais à ce que les heures de création et de modification soient égales. Vous pouvez essayer de changer cela en utilisant touchpour changer l'heure du mod, puis en vérifiant à nouveau.
Carl Smotricz le
9

Sur un système Windows, vous pouvez utiliser la bibliothèque FileTimes gratuite .

Cela sera plus facile à l'avenir avec Java NIO.2 (JDK 7) et le package java.nio.file.attribute .

Mais rappelez-vous que la plupart des systèmes de fichiers Linux ne prennent pas en charge les horodatages de création de fichiers .

Jacek S
la source
Une autre solution pour les machines Linux qui ne prend pas en charge le temps créé?
Maverick
Utilisez simplement un système de fichiers qui prend en charge les horodatages de création de fichiers. L'article Wikipédia lié suggère ext4 qui est assez courant maintenant.
davtom
1

dans java1.7 + Vous pouvez utiliser ce code pour obtenir l'heure de création du fichier!

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
la source
pourriez-vous s'il vous plaît expliquer pourquoi nous avons besoin de cette agitation Instant.ofEpochMilli(date). Merci
Kirill Karmazin