Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File creation date for copied files java nio

Tags:

java

file

nio

I want to find out the creation date of a file and have found several answers here on SO that are quite similar. My problem is that it doesn't work if the file was moved from one folder to another. I didn't modify the file at all - just copied it to another directory.

//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);

To reproduce this you only need to copy an older file and paste it into another directory. The explorer shows the old date but the output of the above code is the time it was copied.

like image 984
wannaBeDev Avatar asked Oct 02 '19 13:10

wannaBeDev


1 Answers

I see the same behavior on Windows 10 using OpenJDK 13. Although you mention the creation time is correct in File Explorer but not when queried via Java. My experience is different; File Explorer shows the correct (i.e. preserved) last modified time but, when I open up the properties dialog for the copy, the creation time is set to when the file was copied.

Note that while not preserving the creation time may be undesirable, I'm not sure this would be considered a bug in Java. The documentation of Files#copy(Path,Path,CopyOption...) says:

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.

- From the description of COPY_ATTRIBUTES in the options table.

As you can see, minimally only the last modified time will be copied and even that is not necessarily guaranteed. This also indicates the problem could be platform-specific; if Windows, or at least the Windows API used by Java, doesn't support preserving the creation time then what you're seeing is expected behavior. But if you believe the behavior is a bug you can always submit a bug report. Before you do, however, make sure a report doesn't already exist, including ones which have been resolved as, for instance, "won't fix".

Note: The above paragraph focuses on Windows. Unfortunately, I don't have access to other operating systems at the moment, so I can't test if those other operating systems have the same problem. You never explicitly mention that you're using Windows, though I assume you are based on the path in your question (i.e. "C:\\Users\\...") and your use of the word "explorer".

That said, I believe a workaround may be possible: Copy the creation time yourself after copying the directory or file:

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

The reason the comment says COPY_ATTRIBUTES should be be included is because, as documented, the option may result in any number of attributes being copied, even if the creation time is not one of them. Of course, if you'd like to make sure the last modified and access times are also copied, you can modify the above into:

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

May be interesting to note that Files#copy(Path,Path,CopyOption...) does something very similar to the second example, but only if the source and target have the different FileSystemProvider instances. Otherwise, the method delegates to the shared FileSystemProvider, which is different for each implementation.

like image 177
Slaw Avatar answered Nov 14 '22 17:11

Slaw