62

I want to change modification timestamp of a binary file. What is the best way for doing this?

Would opening and closing the file be a good option? (I require a solution where the modification of the timestamp will be changed on every platform and JVM).

Yishai
  • 90,445
  • 31
  • 189
  • 263
sinuhepop
  • 20,010
  • 17
  • 72
  • 107

7 Answers7

50

The File class has a setLastModified method. That is what ANT does.

Mmmh mmh
  • 5,334
  • 3
  • 21
  • 29
Yishai
  • 90,445
  • 31
  • 189
  • 263
28

My 2 cents, based on @Joe.M answer

public static void touch(File file) throws IOException{
    long timestamp = System.currentTimeMillis();
    touch(file, timestamp);
}

public static void touch(File file, long timestamp) throws IOException{
    if (!file.exists()) {
       new FileOutputStream(file).close();
    }

    file.setLastModified(timestamp);
}
Community
  • 1
  • 1
Mmmh mmh
  • 5,334
  • 3
  • 21
  • 29
18

Since File is a bad abstraction, it is better to use Files and Path:

public static void touch(final Path path) throws IOException {
    Objects.requireNonNull(path, "path is null");
    try {
        Files.createFile(path);
    } catch (FileAlreadyExistsException e) {
        Files.setLastModifiedTime(path, FileTime.from(Instant.now()));
    }
}
sdgfsdh
  • 33,689
  • 26
  • 132
  • 245
  • `Files.createFile(Path)` also checks for existence of the file. This check and the creation are an atomic operation. I think it’s better to always use `Files.createFile(Path)` and use `Files.setLastModifiedTime` if a `java.nio.file.FileAlreadyExistsException` is thrown. Or use `Path.toFile().createNewFile()` which also does the check and creation in an atomic operation, but uses a `boolean` return code instead of an exception to indicate if the file already existed. – Martin Mar 13 '23 at 12:41
  • @Martin Good point. I have updated the answer to be atomic. It still might fail if (somehow) the file is deleted between the `try` and `catch` though. – sdgfsdh Mar 13 '23 at 16:18
12

Here's a simple snippet:

void touch(File file, long timestamp)
{
    try
    {
        if (!file.exists())
            new FileOutputStream(file).close();
        file.setLastModified(timestamp);
    }
    catch (IOException e)
    {
    }
}
Zach-M
  • 2,127
  • 18
  • 12
8

I know Apache Ant has a Task which does just that.
See the source code of Touch (which can show you how they do it)

They use FILE_UTILS.setFileLastModified(file, modTime);, which uses ResourceUtils.setLastModified(new FileResource(file), time);, which uses a org.apache.tools.ant.types.resources.Touchable, implemented by org.apache.tools.ant.types.resources.FileResource...

Basically, it is a call to File.setLastModified(modTime).

martin clayton
  • 76,436
  • 32
  • 213
  • 198
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
6

This question only mentions updating the timestamp, but I thought I'd put this in here anyways. I was looking for touch like in Unix which will also create a file if it doesn't exist.

For anyone using Apache Commons, there's FileUtils.touch(File file) that does just that.

Here's the source from (inlined openInputStream(File f)):

public static void touch(final File file) throws IOException {
    if (file.exists()) {
        if (file.isDirectory()) {
            throw new IOException("File '" + file + "' exists but is a directory");
        }
        if (file.canWrite() == false) {
            throw new IOException("File '" + file + "' cannot be written to");
        }
    } else {
        final File parent = file.getParentFile();
        if (parent != null) {
            if (!parent.mkdirs() && !parent.isDirectory()) {
                throw new IOException("Directory '" + parent + "' could not be created");
            }
        }
        final OutputStream out = new FileOutputStream(file);
        IOUtils.closeQuietly(out);
    }
    final boolean success = file.setLastModified(System.currentTimeMillis());
    if (!success) {
        throw new IOException("Unable to set the last modification time for " + file);
    }
}
Raekye
  • 5,081
  • 8
  • 49
  • 74
  • There is a race condition between the file.exists and file.setLastModified calls. I.e. this code gets it backwards: FIRST you go ahead and try, THEN you do the post-mortem diagnostics. – toolforger Apr 17 '18 at 12:44
6

If you are already using Guava:

com.google.common.io.Files.touch(file)

Joe23
  • 5,683
  • 3
  • 25
  • 23