Setting/changing the ctime or “Change time” attribute on a file

前端 未结 2 1854
刺人心
刺人心 2020-12-10 07:53

I wish to change the timestamp metadata on files in Java using the java.nio.Files class.

I would like to change all 3 Linux/ext4 timestamps (last modifi

相关标签:
2条回答
  • 2020-12-10 08:10

    Adapting this answer to your case:

    // Warning: Disk must be unmounted before this operation
    String disk = "/dev/sda1";
    // Update ctime
    Runtime.getRuntime().exec("debugfs -w -R 'set_inode_field "+pathToMyFile+" ctime "+myCustomTime+"' "+disk);
    // Drop vm cache so ctime update is reflected
    Runtime.getRuntime().exec("echo 2 > /proc/sys/vm/drop_caches");
    

    I doubt we will see a convenient method in Standard Java API to do this, as neither Linux (man touch) nor Windows (GetFileTime function on MSDN) give easy access to this field. Native system calls give only access to creation/access/modify timestamps, so does Java.

    0 讨论(0)
  • 2020-12-10 08:14

    I was able to modify the ctime with two different methods:

    1. Changing the kernel so that ctime matches the mtime
    2. Writing a simple (but hacky) shell script.

    1st Method: Changing the kernel.

    I tweaked just a few lines in KERNEL_SRC/fs/attr.c This modification updates the ctime to match the mtime whenever the mtime is "explicitly defined."

    There are many ways to "explicitly define" the mtime, for example:

    In Linux:

    touch -m --date="Wed Jun 12 14:00:00 IDT 2013" filename
    

    In Java (using Java 6 or 7, and presumably others):

    long newModificationTime = TIME_IN_MILLIS_SINCE_EPOCH;
    File myFile = new File(myPath);
    newmeta.setLastModified(newModificationTime);
    

    Here is the change to KERNEL_SRC/fs/attr.c in the notify_change function:

        now = current_fs_time(inode->i_sb);
    
        //attr->ia_ctime = now;  (1) Comment this out
        if (!(ia_valid & ATTR_ATIME_SET))
            attr->ia_atime = now;
        if (!(ia_valid & ATTR_MTIME_SET)) {
            attr->ia_mtime = now;
        }
        else { //mtime is modified to a specific time. (2) Add these lines
            attr->ia_ctime = attr->ia_mtime; //Sets the ctime
            attr->ia_atime = attr->ia_mtime; //Sets the atime (optional)
        }
    

    (1) This line, uncommented, would update the ctime to the current clock time upon a change to the file. We don't want that, since we want to set the ctime ourselves. Thus, we comment this line out. (This isn't mandatory)

    (2) This is really the crux of the solution. The notify_change function is executed after a file has been changed, where the time metadata needs to be updated. If no mtime was specified, then the mtime is set to the current time. Else, if the mtime was set to a specific value, we also set the ctime and the atime to that value.

    2nd method: Simple (but hacky) shell script.

    Brief explanation:

    1. Change the system time to your target time
    2. Perform a chmod on the file, file ctime now reflects target time
    3. Revert the system time back.

    changectime.sh

    #!/bin/sh
    now=$(date)
    echo $now
    sudo date --set="Sat May 11 06:00:00 IDT 2013"
    chmod 777 $1
    sudo date --set="$now"
    

    Run this as follows: ./changectime.sh MYFILE

    The file's ctime will now reflect the time in the file.

    Of course, you probably don't want the file with 777 permissions. Ensure that you modify this script to your needs before using it.

    0 讨论(0)
提交回复
热议问题