Windows下使用C/C++修改文件时间

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013774469/article/details/82390404

背景

在某些特定场景下,会有修改文件创建时间、修改时间的需求。具体为什么要修改文件时间就不去纠结了,感兴趣的可以去做个问卷调查,也可以自行脑补,反正经常有小伙伴问怎么去修改文件时间。

最简单的解决方案

文件的时间作为文件的属性,当然是由文件的编辑工具生成或修改的。那么最简单的方式就是把你的系统时间设置为想要改的时间点,比如设置为2000年1月1日的某个时间点,然后打开文件编辑工具,随便修改点内容,比如在某个位置敲一个字符然后删除并保存,虽然文件的内容没变,但是文件的修改时间已经变为2000年1月1日。然而你会发现,文件的创建时间没有更改,所以你需要将文件另存为某个文件,你就会发现另存为的文件的创建时间变成了你想要的时间。这个时候你就可以拿这个另存为的文件去交差了,一切很简单。

缺点
1、修改系统时间很简单,但是总是不想改,嫌麻烦。
2、需要修改或另存为文件,批量修改文件时间不被累死就被烦死。
3、有些文件压根就找不到对应的编辑工具,谈何修改或另存为。
4、太低效。

最简单高效的解决方案

最简单高效的方式,当然是调用系统接口,直接修改文件时间为自己指定的时间。

原理

在windows系统中,修改文件的时间属性一般都是调用API直接修改,C/C++ API如下:

BOOL SetFileTime(
  HANDLE         hFile,
  CONST FILETIME *lpCreationTime,
  CONST FILETIME *lpLastAccessTime,
  CONST FILETIME *lpLastWriteTime
);

详细的API说明在微软官方文档页面上有介绍,可以自行到微软官方文档页面进行搜索查询。

实现Demo

以下采用C语言实现,以便参考,读者可以采用自己擅长的语言自行实现。

#include "windows.h"
#include "stdio.h"
#include "stdlib.h"

int main(int argc, char *argv[]) {
    // 传参格式: 可执行程序.exe fileName time
    // 传参示例:App.exe test.txt 2018-09-04 20:28:50

    // 参数检查
    if( argc != 4 ) {
        printf("Use format: %s fileName time\nUse like: %s test.txt 2018-09-04 20:28:50\n", argv[0], argv[0]);
        return -1;
    }

    // 检查时间格式
    if( strlen(argv[2]) != 10 || strlen(argv[3]) != 8 ) {
        printf("Time format is invalid, time format like: 2018-09-04 20:28:50\n");
        return -1;
    }

    // 读取指定时间
    SYSTEMTIME spec_time;
    sscanf(argv[2],"%d-%d-%d", &spec_time.wYear, &spec_time.wMonth, &spec_time.wDay);
    sscanf(argv[3],"%d:%d:%d", &spec_time.wHour, &spec_time.wMinute, &spec_time.wSecond);
    spec_time.wDayOfWeek    = 1;
    spec_time.wMilliseconds = 0;
    // TODO: 此处省略对时间有效性的校验

    // 获取文件句柄
    HANDLE hFile = CreateFile(argv[1],      // LPCTSTR lpFileName,
        GENERIC_READ|GENERIC_WRITE,         // DWORD dwDesiredAccess,
        FILE_SHARE_READ|FILE_SHARE_DELETE,
        NULL,                               // LPSECURITY_ATTRIBUTES lpSecurityAttributes,
        OPEN_EXISTING,
        FILE_FLAG_BACKUP_SEMANTICS,         // DWORD dwFlagsAndAttributes,
        NULL);

    if( hFile == INVALID_HANDLE_VALUE ) {
        printf("Get file handle failed, error = %s\n", GetLastError());
        return -1;
    }

    // 设置文件时间
    FILETIME ft,LocalFileTime;
    SystemTimeToFileTime(&spec_time, &ft);
    LocalFileTimeToFileTime(&ft,&LocalFileTime);

    if(SetFileTime(hFile,&LocalFileTime,(LPFILETIME) NULL,&LocalFileTime)) {
        printf("Set file time success\n");
    }else{
        printf("Set file time failed\n");
    }
    CloseHandle(hFile);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u013774469/article/details/82390404