复制文件的文件创建日期 java nio

File creation date for copied files java nio

我想找出文件的创建日期,并在 SO 上找到了几个非常相似的答案。我的问题是,如果文件从一个文件夹移动到另一个文件夹,它就不起作用。我根本没有修改文件 - 只是将它复制到另一个目录。

//file location before copy paste C:\Users\momo\temp\A.csv
File f = new File("C:\Users\momo\temp\xyz\A.csv");
BasicFileAttributes attributes = Files.readAttributes(Paths.get(f.toURI()), BasicFileAttributes.class);
FileTime fileTime = attributes.creationTime();
Date date = new Date(fileTime.toMillis());
System.out.println(date);

要重现此文件,您只需复制一个旧文件并将其粘贴到另一个目录中。资源管理器显示旧日期,但上面代码的输出是它被复制的时间。

我在使用 OpenJDK 13 的 Windows 10 上看到了相同的行为。虽然您提到文件资源管理器中的创建时间是正确的,但通过 Java 查询时却不是。我的经历不同;文件资源管理器显示正确的(即保留的)上次修改时间,但是,当我打开副本的属性对话框时,设置了创建时间复制文件的时间。

请注意,虽然不保留创建时间可能是不可取的,但我不确定这是否会被视为 Java 中的错误。 Files#copy(Path,Path,CopyOption...) 的文档说:

Attempts to copy the file attributes associated with this file to the target file. The exact file attributes that are copied is platform and file system dependent and therefore unspecified. Minimally, the last-modified-time is copied to the target file if supported by both the source and target file stores. Copying of file timestamps may result in precision loss.

- 来自选项table中COPY_ATTRIBUTES的描述。

如您所见,至少只有最后修改时间会被复制,即使这样也不一定能保证。这也表明问题可能是特定于平台的;如果 Windows,或者至少 Java 使用的 Windows API 不支持保留创建时间,那么您所看到的就是预期的行为。但是,如果您认为该行为是一个错误,您总是可以 submit a bug report. Before you do, however, make sure a report doesn't already exist,包括已解决的问题,例如,“不会修复”。

注:以上段落重点在Windows。不幸的是,我目前无法访问其他操作系统,所以我无法测试其他操作系统是否有同样的问题。你从未明确提到你正在使用 Windows,尽管我假设你是基于问题中的路径(即 "C:\Users\...")和你对 "explorer".[=47 这个词的使用=]

也就是说,我认为可能有一个解决方法:复制目录或文件后自己复制创建时间:

Files.copy(source, target, options); // 'options' should include COPY_ATTRIBUTES
Files.setAttribute(target, "creationTime", Files.getAttribute(source, "creationTime"));

评论说 COPY_ATTRIBUTES 应该被包括在内的原因是,如文档所述,该选项可能导致复制任意数量的属性,即使创建时间不是其中之一。当然,如果你想确保最后修改时间和访问时间也被复制,你可以将上面的修改为:

Files.copy(source, target, options); // 'options' should include COPY_ATTRIBUTES

BasicFileAttributes srcAttrs = Files.readAttributes(source, BasicFileAttributes.class);
BasicFileAttributeView tgtView = Files.getFileAttributeView(target, BasicFileAttributeView.class);

tgtView.setTimes(srcAttrs.lastModifiedTime(), srcAttrs.lastAccessTime(), srcAttrs.creationTime());

有趣的是,Files#copy(Path,Path,CopyOption...) 做的事情与第二个示例非常相似,但前提是源和目标具有不同的 FileSystemProvider 实例。否则,该方法委托给共享 FileSystemProvider,每个实现都不同。