#2871 Is it possible to change file attributes using Fantom?

LightDye Sat 28 May 2022

Hi all,

I'm writing a Fantom program to copy files from one directory to another. I'm using File.copyTo method. Something like this:

File( `file.txt` ).copyTo( File( `copy.txt` ) )

The problem is that the resulting copy gets its creation and modification times set to the current system time, not the times of the source file, such as doing:

cp file.txt copy.txt

The behaviour I want is this instead:

cp -p file.txt copy.txt

where the file attributes of the source are also copied to the destination file, including creation and modification times.

I'm currently using an OS command to reset the times of the copy, but this is less than ideal, and not very portable. This is what I'm doing for macOS, where timestamp is a DateTime instance with the original creation time:

tzTime := timestamp.toUtc
macOsTimestamp := tzTime.toLocale( "YYYYMMDDhhmm.ss" )
cmdToChangeModifiedTime := Process( ["touch", "-m", "-t", macOsTimestamp, file.pathStr ] )
cmdToChangeModifiedTime.run.join

Is there any way of doing this using only Fantom, please?

SlimerDude Sun 29 May 2022

Hi, there's nothing that I've used (or know of) in Fantom, but this StackOverflow post says it can be done in Java using Files.copy().

The corresponding Fantom code would look something like this:

using [java] fanx.interop::Interop
using [java] java.nio.file::Files
using [java] java.nio.file::StandardCopyOption

...

Files.copy(
    Interop.toJava(`src.txt`.toFile).toPath,
    Interop.toJava(`dst.txt`.toFile).toPath,
    [StandardCopyOption.COPY_ATTRIBUTES]
)

brian Sun 29 May 2022

Note that sys::File.copyInto will copy file permissions. I don't think it does timestamps, but sys::File.modified is a field you can set.

LightDye Sun 29 May 2022

Hi Brian, Steve,

Both solutions work nicely. Thank you both. I ended up using the modified field (I don't know why I assumed it was a read-only field when I first saw it). Now I'm doing:

file := File( `file.txt` )
copy := file.copyTo( File( `copy.txt` ) )
copy.modified = file.modified

and that does exactly what I need.

Thank you Steve for providing the example showing JavaFFI and Interop usage. It's something I haven't used before, but I'm pretty sure it will come handy soon.

Login or Signup to reply.