【问题标题】:Determine file creation date in Java在 Java 中确定文件创建日期
【发布时间】:2010-04-27 18:19:46
【问题描述】:

在 StackOverflow (How to get creation date of a file in Java) 上还有另一个类似的问题要我解决,但答案并不真正存在,因为 OP 有不同的需求,可以通过其他机制解决。我正在尝试在可以按年龄排序的目录中创建文件列表,因此需要文件创建日期。

在网上搜索了很多之后,我还没有找到任何好的方法来做到这一点。是否有获取文件创建日期的机制?

顺便说一句,目前在 Windows 系统上,可能也需要它在 Linux 系统上工作。此外,我不能保证在名称中嵌入创建日期/时间时会遵循文件命名约定。

【问题讨论】:

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

标签: java date filesystems


【解决方案1】:

Java nio 具有访问creationTime 和其他元数据的选项,只要文件系统提供它。 签出this link

例如(根据@ydaetskcoR的评论提供):

Path file = ...;
BasicFileAttributes attr = Files.readAttributes(file.toPath(), BasicFileAttributes.class);

System.out.println("creationTime: " + attr.creationTime());
System.out.println("lastAccessTime: " + attr.lastAccessTime());
System.out.println("lastModifiedTime: " + attr.lastModifiedTime());

【讨论】:

  • 这是最好的,但它是 Java 7。我们仍在使用 6,但我会研究我们的升级选项。
  • 使用 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 别担心,伙计!试试这个logicbig.com/how-to/java/file-creation-date.html
  • 文件创建日期在 JDK 8 上(至少)不可用,因为在较新的 Linux 内核版本中添加了 statx syscall。
  • 但是为什么创建时间总是和上次修改时间一样呢?
【解决方案2】:

我已经使用 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));
        }
    }
}

【讨论】:

    【解决方案3】:

    作为这个问题的后续 - 因为它与创建时间特别相关,并讨论了通过新的 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);
        }
      }
    }
    

    【讨论】:

    • 你知道如何在 Android 上做到这一点吗? BasicFileAttributes 在 API 中不可用...
    • 确实如此,即使调用stat 也不起作用。除非你碰巧运行高于 4.11 的内核,使用高于 2.28 的 glibc 和高于 8.31 的 coreutils,否则stat 将报告文件的birth。见相关回答unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4/…目前JDK不使用statx syscal。
    【解决方案4】:

    这是一个基本示例,说明如何使用BasicFileAttributes 类获取Java 中文件的创建日期:

       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 中发布。
    【解决方案5】:

    java.io.File 的 API 只支持获取最后一次修改时间。互联网上也对这个话题非常安静。

    除非我遗漏了一些重要的东西,否则 Java 库(直到 Java 7,但尚未包括在内)不包含此功能。因此,如果您对此感到绝望,一种解决方案是编写一些 C(++) 代码来调用系统例程并使用 JNI 调用它。不过,大部分工作似乎已经在一个名为 JNA 的库中为您完成。

    不过,您可能仍需要用 Java 编写一些特定于操作系统的代码,因为您可能无法在 Windows 和 Unix/Linux/BSD/OS X 中找到相同的系统调用。

    【讨论】:

    • 是的,Java 7 会很棒,因为 nio 似乎在基本属性中具有此功能。从没想过我会抱怨出生太早! ;)
    • File 类没有此功能的原因是大多数文件系统甚至不跟踪此信息。而那些确实在何时应该更新的问题上并不总是达成一致。
    • @Syntactic:实际上是most filesystems do track this information。例外情况包括 ext
    • @Carl 在 linux 中,我在使用 Java NIO 时得到了相同的修改和创建日期。这是正常行为吗?
    • @JayeshDhandha,如果在创建文件后没有任何修改,我会期望创建和修改时间相等。您可以尝试使用touch 更改模组时间,然后再次检查。
    【解决方案6】:

    在 Windows 系统上,您可以使用免费的FileTimes 库。

    Java NIO.2 (JDK 7) and the java.nio.file.attribute package 将来会更容易。

    但请记住,大多数 Linux 文件系统 don't support file creation timestamps

    【讨论】:

    • 对于不支持创建时间的 linux 机器还有其他方法吗?
    • 只需使用支持文件创建时间戳的文件系统即可。链接的维基百科文章建议使用 ext4,这现在很常见。
    【解决方案7】:

    在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) 的这种喧嚣。谢谢
    猜你喜欢
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    相关资源
    最近更新 更多