Determina la data di creazione del file in Java


102

C'è un'altra domanda simile alla mia su StackOverflow ( come ottenere la data di creazione di un file in Java ), ma la risposta non è davvero lì poiché l'OP aveva una necessità diversa che poteva essere risolta tramite altri meccanismi. Sto cercando di creare un elenco dei file in una directory che può essere ordinata per età, da qui la necessità della data di creazione del file.

Non ho trovato alcun buon modo per farlo dopo molte ricerche sul web. Esiste un meccanismo per ottenere le date di creazione dei file?

BTW, attualmente su un sistema Windows, potrebbe aver bisogno di questo per funzionare anche su un sistema Linux. Inoltre, non posso garantire che venga seguita una convenzione di denominazione dei file in cui la data / ora di creazione è incorporata nel nome.


2
Ok, dopo ulteriori discussioni e indagini sui filesystem, abbiamo deciso che l'uso dell'ultima modifica è sufficiente poiché probabilmente avrebbe dovuto essere controllato insieme alla data di creazione. Entrambi dovrebbero essere controllati per determinare se un vecchio file è stato modificato di recente e quindi ancora attivo. Quindi, controlla solo il file modificato più lontano in passato. Grazie per tutti gli input. BTW, mi piacerebbe usare nio, ma il sapore Linux qui non supporta comunque la creazione di file.
Todd

Risposte:


163

Java nio ha opzioni per accedere a creationTime e altri metadati fintanto che il filesystem lo fornisce. Controllare questo link out

Ad esempio (fornito in base al commento di @ 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());

16
Sarebbe la cosa migliore, ma è Java 7. Stiamo ancora usando 6, ma esaminerò le nostre opzioni di aggiornamento.
Todd

1
Fantastico. Ne avevo esattamente bisogno.
RestInPeace

7
usa readAttributes(file.toPath(), BasicFileAttributes.class)altrimenti ottieni: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 Nessun problema, amico! Prova questo logicbig.com/how-to/java/file-creation-date.html .
Socrate

1
La data di creazione del file non è disponibile su JDK 8 (almeno) poiché statxsyscall è stato aggiunto nella versione più recente del kernel Linux.
Sant'Antario

15

Ho risolto questo problema usando JDK 7 con questo codice:

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));
        }
    }
}

13

In seguito a questa domanda - poiché si riferisce specificamente al tempo di creazione e discute come ottenerlo tramite le nuove classi nio - sembra che in questo momento nell'implementazione di JDK7 tu sia sfortunato. Addendum: lo stesso comportamento è in OpenJDK7.

Su filesystem Unix non è possibile recuperare il timestamp di creazione, si ottiene semplicemente una copia dell'ora dell'ultima modifica. Così triste, ma purtroppo vero. Non sono sicuro del motivo, ma il codice lo fa specificamente come dimostrerà di seguito.

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);
    }
  }
}

1
Sai come farlo per Android? BasicFileAttributes non è disponibile come API integrata lì ...
sviluppatore Android

Questo è davvero vero, anche una chiamata a statnon funziona. A meno che non ti capiti di eseguire un kernel superiore a 4.11 con glibc maggiore di 2.28 e coreutils maggiore di 8.31, allora statriporterà la nascita del file. Vedi la risposta correlata unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4/… Attualmente il JDK non usa statx syscal.
Brice

12

Questo è un esempio di base di come ottenere la data di creazione di un file Java, utilizzando 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());
}

Le persone che desiderano utilizzare questa classe dovrebbero notare che ha iniziato a essere distribuito in Java 1.7.
jwj

9

L'API di java.io.Filesupporta solo il recupero dell'ultima ora modificata . E anche su questo argomento Internet è molto silenzioso.

A meno che non mi sia perso qualcosa di significativo, la libreria Java così com'è (fino a, ma non include ancora Java 7) non include questa funzionalità. Quindi, se tu fossi disperato per questo, una soluzione sarebbe scrivere del codice C (++) per chiamare le routine di sistema e chiamarlo usando JNI. La maggior parte di questo lavoro sembra essere già fatto per te in una libreria chiamata JNA , però.

Potrebbe comunque essere necessario eseguire un po 'di codifica specifica del sistema operativo in Java per questo, tuttavia, poiché probabilmente non troverai le stesse chiamate di sistema disponibili in Windows e Unix / Linux / BSD / OS X.


2
Sì, Java 7 sarebbe fantastico in quanto il nio sembra averlo negli attributi di base. Non avrei mai pensato che mi sarei lamentato di essere nato troppo presto! ;)
Todd

6
Il motivo per cui la Fileclasse non ha questa capacità è che la maggior parte dei filesystem non tiene nemmeno traccia di queste informazioni. E quelli che non sono sempre d'accordo su quando dovrebbe essere aggiornato.
Sintattico

@Syntactic: In realtà la maggior parte dei filesystem tiene traccia di queste informazioni . Le eccezioni includono ext <= 3 e Reiser. FAT, NTFS, HFS, ZFS ed ext4 lo supportano. Ma è stato lento a propagarsi attraverso tutti i livelli di Linux e le librerie e i comandi per renderlo universalmente utilizzato.
Hippietrail

@Carl In Linux, ricevo la stessa data di modifica e creazione mentre utilizzo Java NIO. È il comportamento normale?
Jayesh Dhandha

@JayeshDhandha, se nulla modifica il file dopo che è stato creato, mi aspetto che i tempi di creazione e modifica siano uguali. Potresti provare a cambiarlo usando touchper cambiare l'ora della mod e quindi ricontrollare.
Carl Smotricz

9

Su un sistema Windows, puoi utilizzare la libreria FileTimes gratuita .

Questo sarà più facile in futuro con Java NIO.2 (JDK 7) e il pacchetto java.nio.file.attribute .

Ma ricorda che la maggior parte dei filesystem Linux non supporta i timestamp per la creazione di file .


Qualche altro modo per aggirare le macchine Linux che non supportano il tempo creato?
Maverick

Usa semplicemente un file system che supporta i timestamp per la creazione di file. L'articolo di Wikipedia collegato suggerisce ext4 che è abbastanza comune ora.
davtom

1

in java1.7 + Puoi usare questo codice per ottenere l'ora di creazione del file!

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());
    }

potresti spiegarci perché abbiamo bisogno di questo trambusto Instant.ofEpochMilli(date). Grazie
Kirill Karmazin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.