Determine a data de criação do arquivo em Java


102

Há outra questão semelhante a minha no StackOverflow ( como obter a data de criação de um arquivo em Java ), mas a resposta não está realmente lá, pois o OP tinha uma necessidade diferente que poderia ser resolvida por meio de outros mecanismos. Estou tentando criar uma lista dos arquivos em um diretório que pode ser classificado por idade, daí a necessidade da data de criação do arquivo.

Não encontrei uma boa maneira de fazer isso depois de pesquisar muito na web. Existe um mecanismo para obter as datas de criação do arquivo?

BTW, atualmente em um sistema Windows, pode precisar disso para funcionar em um sistema Linux também. Além disso, não posso garantir que uma convenção de nomenclatura de arquivo seja seguida onde a data / hora de criação está embutida no nome.


2
Ok, depois de mais discussões e investigações nos sistemas de arquivos, decidimos que usar a última modificação é suficiente, uma vez que provavelmente teria que ser verificado junto com a data de criação. Ambos precisariam ser verificados para determinar se um arquivo antigo foi modificado recentemente e, portanto, ainda está ativo. Portanto, apenas verifique o arquivo modificado mais distante no passado. Obrigado por todas as contribuições. BTW, eu adoraria usar o nio, mas o tipo Linux aqui não suporta a criação de arquivos de qualquer maneira.
Todd

Respostas:


163

Java nio tem opções para acessar o creationTime e outros metadados, desde que o sistema de arquivos os forneça. Confira neste link para fora

Por exemplo (fornecido com base no comentário 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());

16
Seria melhor, mas é o Java 7. Ainda estamos usando o 6, mas investigarei nossas opções de atualização.
Todd

1
Fantástico. Exatamente eu precisava.
RestInPeace

7
use readAttributes(file.toPath(), BasicFileAttributes.class)outra coisa que você obtém: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 Não se preocupe, cara! Experimente este logicbig.com/how-to/java/file-creation-date.html .
Sócrates de

1
A data de criação do arquivo não está disponível no JDK 8 (pelo menos) desde que o statxsyscall foi adicionado na versão mais recente do kernel Linux.
St.Antario

15

Resolvi esse problema usando o JDK 7 com este código:

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

Seguindo essa questão - uma vez que se relaciona especificamente ao tempo de criação e discute como obtê-lo por meio das novas classes nio - parece que agora na implementação do JDK7 você está sem sorte. Adendo: o mesmo comportamento é no OpenJDK7.

Em sistemas de arquivos Unix, você não pode recuperar o carimbo de data e hora da criação, simplesmente obtém uma cópia da hora da última modificação. Tão triste, mas infelizmente é verdade. Não sei por que isso acontece, mas o código faz isso especificamente, conforme demonstrará a seguir.

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
Você sabe como fazer isso no Android? BasicFileAttributes não está disponível como API integrada lá ...
desenvolvedor de Android

Isso é verdade, mesmo uma chamada para statnão funciona. A menos que você execute um kernel superior a 4.11 com glibc superior a 2.28 e coreutils superior a 8.31, então statirá relatar o nascimento do arquivo. Veja a resposta relacionada unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4/… Atualmente o JDK não usa statx syscal.
Brice de

12

Este é um exemplo básico de como obter a data de criação de um arquivo Java, usando a 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());
}

As pessoas que desejam usar essa classe devem observar que ela começou a ser enviada em Java 1.7.
jwj

9

A API de java.io.Filesuporta apenas a última modificação hora . E a Internet também não fala muito sobre esse assunto.

A menos que eu tenha perdido algo significativo, a biblioteca Java como está (até mas ainda não incluindo o Java 7) não inclui esse recurso. Portanto, se você estivesse desesperado por isso, uma solução seria escrever algum código C (++) para chamar as rotinas do sistema e chamá-lo usando JNI. A maior parte deste trabalho parece já ter sido feita para você em uma biblioteca chamada JNA , no entanto.

Você ainda pode precisar fazer uma pequena codificação específica do sistema operacional em Java para isso, pois provavelmente não encontrará as mesmas chamadas de sistema disponíveis no Windows e Unix / Linux / BSD / OS X.


2
Sim, Java 7 seria ótimo, pois o nio parece ter isso em atributos básicos. Nunca pensei que reclamaria por ter nascido muito cedo! ;)
Todd,

6
A razão pela qual a Fileclasse não tem esse recurso é que a maioria dos sistemas de arquivos nem mesmo rastreia essas informações. E aqueles que concordam nem sempre concordam quando deve ser atualizado.
Syntactic

@Syntactic: Na verdade, a maioria dos sistemas de arquivos rastreia essas informações . As exceções incluem ext <= 3 e Reiser. FAT, NTFS, HFS, ZFS e ext4 são compatíveis. Mas tem sido lento para se propagar por todas as camadas do Linux e as bibliotecas e comandos para torná-lo universalmente usado.
hippietrail

@Carl No linux, estou obtendo a data de modificação e criação da mesma forma ao usar o Java NIO. É o comportamento normal?
Jayesh Dhandha

@JayeshDhandha, se nada modificar o arquivo depois de criado, esperaria que os tempos de criação e modificação fossem iguais. Você pode tentar mudar isso usando touchpara mudar o tempo do mod e depois verificar novamente.
Carl Smotricz

9

Em um sistema Windows, você pode usar FileTimes grátis biblioteca .

Isso será mais fácil no futuro com Java NIO.2 (JDK 7) e o pacote java.nio.file.attribute .

Mas lembre-se de que a maioria dos sistemas de arquivos Linux não oferece suporte a carimbos de data / hora de criação de arquivo .


Alguma outra maneira de contornar as máquinas Linux que não suportam o tempo criado?
Maverick de

Basta usar um sistema de arquivos que suporte carimbos de data / hora de criação de arquivo. O artigo da Wikipedia com link sugere ext4, que é bastante comum agora.
davtom

1

em java1.7 + Você pode usar este código para obter o tempo de criação do arquivo!

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

você poderia explicar por que precisamos dessa agitação Instant.ofEpochMilli(date). Obrigado
Kirill Karmazin
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.