确定Java中的文件创建日期


102

在StackOverflow上还有一个类似的问题要问(如何在Java中获取文件的创建日期),但实际上并没有答案,因为OP具有可以通过其他机制解决的不同需求。我试图在目录中创建文件列表,该文件列表可以按年龄排序,因此需要文件创建日期。

经过大量的网络搜寻,我还没有找到任何好的方法来执行此操作。是否有获取文件创建日期的机制?

当前在Windows系统上的BTW可能也需要在Linux系统上工作。另外,我不能保证在名称中嵌入创建日期/时间的情况下,将遵循文件命名约定。


2
好的,在对文件系统进行了更多讨论和调查之后,我们决定使用last Modify就足够了,因为可能必须将其与创建日期一起进行检查。这两个都需要检查以确定旧文件是否最近被修改了并因此仍然处于活动状态。因此,只需检查过去修改过的文件即可。感谢所有的投入。顺便说一句,我很想使用nio,但是这里的Linux版本仍然不支持文件创建。
Todd

Answers:


163

只要文件系统提供了Java nio,就可以选择访问creationTime和其他元数据。检查此链接

例如(根据@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
最好,但这是Java7。我们仍在使用6,但我将研究升级选项。
托德(Todd)

1
太棒了 我确实需要。
RestInPeace 2015年

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))
霍利

1
@Hooli朋友,不用担心!试试这个logicbig.com/how-to/java/file-creation-date.html
苏格拉底

1
至少在JDK 8上没有文件创建日期,因为statxsyscall是在较新的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。
布莱斯

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

希望使用此类的人们应该注意,它从Java 1.7开始交付。
jwj

9

该API java.io.File仅支持获取上次修改时间。互联网在此主题上也非常安静。

除非我错过了重要的事情,否则Java库(直到但尚未包括Java 7)都不包含此功能。因此,如果您不顾一切,一种解决方案是编写一些C(++)代码以调用系统例程并使用JNI对其进行调用。不过,大多数工作似乎已经在名为JNA的库中为您完成了。

但是,您可能仍需要为此用Java做一些特定于OS的编码,因为您可能找不到Windows和Unix / Linux / BSD / OS X中可用的相同系统调用。


2
是的,因为nio似乎在基本属性中具有Java 7,所以Java 7会很棒。没想到我会抱怨过早出生!;)
Todd

6
File该类不具有此功能的原因是,大多数文件系统甚至都不跟踪此信息。那些并不总是同意何时更新它的人。
语法

@Syntactic:实际上大多数文件系统都跟踪此信息。例外包括ext <= 3和Reiser。FAT,NTFS,HFS,ZFS和ext4支持它。但是,在Linux的所有层以及用于使其普遍使用的库和命令中传播一直很慢。
hippietrail

@Carl在Linux中,使用Java NIO时获得的修改和创建日期相同。这是正常行为吗?
Jayesh Dhandha

@JayeshDhandha,如果文件创建后没有任何修改,我希望创建和修改时间相等。您可以尝试通过touch更改mod时间然后再次检查来更改它。
Carl Smotricz


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)。谢谢
Kirill Karmazin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.