Определить дату создания файла в Java

102

Есть еще один похожий вопрос на StackOverflow ( как получить дату создания файла на Java ), но ответа на самом деле нет, поскольку у OP была другая потребность, которую можно было решить с помощью других механизмов. Я пытаюсь создать список файлов в каталоге, который можно отсортировать по возрасту, отсюда и необходимость в дате создания файла.

Я не нашел хорошего способа сделать это после долгого рыскания в сети. Есть ли механизм получения дат создания файлов?

Кстати, в настоящее время в системе Windows, возможно, это понадобится для работы и в системе Linux. Кроме того, я не могу гарантировать, что будет соблюдаться соглашение об именах файлов, если дата / время создания встроены в имя.

Тодд
источник
2
Хорошо, после дальнейших обсуждений и исследований файловых систем мы решили, что достаточно использовать последнее изменение, так как его, вероятно, нужно было бы проверить вместе с датой создания. Оба должны быть проверены, чтобы определить, был ли старый файл недавно изменен и, следовательно, все еще активен. Итак, просто проверьте файл, измененный наиболее далеко в прошлом. Спасибо за ваш вклад. Кстати, я бы хотел использовать nio, но Linux здесь все равно не поддерживает создание файлов.
Тодд

Ответы:

165

В Java nio есть опции для доступа к createTime и другим метаданным, если их предоставляет файловая система. Проверить эту ссылку из

Например (предоставлено на основе комментария @ 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
Это было бы лучше всего, но это Java 7. Мы все еще используем 6, но я изучу наши варианты обновления.
Тодд,
1
Фантастика. Именно мне и нужно.
RestInPeace
7
используйте readAttributes(file.toPath(), BasicFileAttributes.class)еще вы получите: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 Не беспокойся, приятель! Попробуйте это logicbig.com/how-to/java/file-creation-date.html .
Сократ
1
Дата создания файла недоступна в JDK 8 (по крайней мере), поскольку statxсистемный вызов был добавлен в более новую версию ядра Linux.
Сент-Антарио
15

Я решил эту проблему с помощью JDK 7 с помощью этого кода:

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

В продолжение этого вопроса - поскольку он относится конкретно ко времени создания и обсуждает его получение с помощью новых классов nio - кажется, что прямо сейчас в реализации JDK7 вам не повезло. Приложение: такое же поведение и в OpenJDK7.

В файловых системах Unix вы не можете получить метку времени создания, вы просто получаете копию времени последней модификации. Так грустно, но, к сожалению, это правда. Я не уверен, почему это так, но код специально делает это, как показано ниже.

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
Вы знаете, как это сделать для Android? BasicFileAttributes недоступен как встроенный в API ...
разработчик Android
Это действительно так, даже призыв statне работает. Если только вы не запускаете ядро ​​выше 4.11 с glibc выше 2.28 и coreutils выше 8.31, тогда statбудет сообщено о рождении файла. См. Соответствующий ответ unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4/… В настоящее время JDK не использует statx syscal.
Brice
12

Это базовый пример того, как получить дату создания файла с Javaпомощью BasicFileAttributesкласса:

   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
источник
Люди, желающие использовать этот класс, должны отметить, что он начал поставляться в Java 1.7.
jwj
10

В системе Windows вы можете использовать бесплатные FileTimes библиотеку .

В будущем это будет проще с Java NIO.2 (JDK 7) и пакетом java.nio.file.attribute. .

Но помните, что большинство файловых систем Linux не поддерживают отметки времени создания файлов .

Яцек С
источник
Любой другой способ для Linux-машин, которые не поддерживают созданное время?
Maverick
Просто используйте файловую систему, которая поддерживает временные метки создания файлов. Связанная статья в Википедии предлагает ext4, который сейчас довольно распространен.
давтом
9

API java.io.Fileподдерживает только получение времени последнего изменения . И в Интернете тоже очень тихо по этой теме.

Если я не пропустил что-то существенное, библиотека Java как есть (вплоть до Java 7, но еще не включая) не включает эту возможность. Поэтому, если вы отчаянно в этом нуждались, одним из решений было бы написать код C (++) для вызова системных подпрограмм и вызвать его с помощью JNI. Однако большая часть этой работы, похоже, уже сделана за вас в библиотеке JNA .

Тем не менее, вам может потребоваться немного кодирования для конкретной ОС на Java, поскольку вы, вероятно, не найдете те же системные вызовы, доступные в Windows и Unix / Linux / BSD / OS X.

Карл Смотрич
источник
2
Да, Java 7 была бы замечательной, поскольку у nio, похоже, это есть в основных атрибутах. Никогда не думала, что буду жаловаться на то, что родилась слишком рано! ;)
Тодд
7
Причина, по которой Fileкласс не имеет такой возможности, заключается в том, что большинство файловых систем даже не отслеживают эту информацию. А те, кто этого не делает, не всегда соглашаются, когда его следует обновлять.
Syntactic
@Syntactic: На самом деле большинство файловых систем отслеживают эту информацию . Исключения включают ext <= 3 и Reiser. FAT, NTFS, HFS, ZFS и ext4 поддерживают его. Но он медленно распространяется на все уровни Linux, библиотеки и команды, чтобы сделать его универсальным.
hippietrail
@Carl В Linux я получаю дату модификации и создания, как и при использовании Java NIO. Это нормальное поведение?
Джайеш Дхандха
@JayeshDhandha, если ничего не изменяет файл после его создания, я бы ожидал, что время создания и модификации будет одинаковым. Вы можете попробовать изменить это, используя touchдля изменения времени мода, а затем снова проверить.
Карл Смотриц,
1

в java1.7 + Вы можете использовать этот код, чтобы узнать время создания файла!

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());
    }
Чжансиньцян
источник
не могли бы вы уточнить, зачем нам эта суета Instant.ofEpochMilli(date). Спасибо
Кирилл Кармазин