C语言如何用GetFileTime获取文件时间?

99ANYc3cd6
预计阅读时长 21 分钟
位置: 首页 C语言 正文

在 Windows 系统上,这个功能主要通过 Win32 API 函数 GetFileTime 来实现,这是一个非常底层的 API,直接操作 Windows 文件系统。

c语言 getfiletime
(图片来源网络,侵删)

核心概念

  1. 文件时间:在 Windows 中,文件时间不是我们通常使用的 struct tm(年、月、日、时、分、秒),而是从 1601 年 1 月 1 日 UTC (协调世界时) 开始的 100 纳秒间隔数,这是一个 64 位整数,类型是 FILETIME
  2. FILETIME 结构体
    typedef struct _FILETIME {
        DWORD dwLowDateTime;  // 低32位
        DWORD dwHighDateTime; // 高32位
    } FILETIME;
  3. 三种时间
    • Creation Time (创建时间): 文件被创建的时间。
    • Last Access Time (最后访问时间): 文件最后一次被读取或执行的时间。
    • Last Write Time (最后修改时间): 文件最后一次被写入的时间,这是最常用的时间。

核心函数

GetFileTime

这是获取文件时间的核心函数。

函数原型:

BOOL GetFileTime(
  HANDLE         hFile,                // 文件的句柄
  LPFILETIME     lpCreationTime,       // 用于接收创建时间的 FILETIME 结构体指针
  LPFILETIME     lpLastAccessTime,     // 用于接收最后访问时间的 FILETIME 结构体指针
  LPFILETIME     lpLastWriteTime       // 用于接收最后修改时间的 FILETIME 结构体指针
);

参数说明:

  • hFile: 一个已打开文件的句柄,你必须先通过 CreateFile 函数获取这个句柄。
  • lpCreationTime: 指向 FILETIME 结构体的指针,用于接收文件的创建时间,如果你不需要,可以传入 NULL
  • lpLastAccessTime: 指向 FILETIME 结构体的指针,用于接收文件的最后访问时间,如果你不需要,可以传入 NULL
  • lpLastWriteTime: 指向 FILETIME 结构体的指针,用于接收文件的最后修改时间,如果你不需要,可以传入 NULL

返回值:

c语言 getfiletime
(图片来源网络,侵删)
  • 成功返回 TRUE (非零)。
  • 失败返回 FALSE (零),可以通过调用 GetLastError() 获取详细的错误信息。

CreateFile

在调用 GetFileTime 之前,你必须先打开文件并获取其句柄。

函数原型:

HANDLE CreateFile(
  LPCSTR                lpFileName,      // 文件名
  DWORD                 dwDesiredAccess, // 访问模式
  DWORD                 dwShareMode,     // 共享模式
  LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全属性
  DWORD                 dwCreationDisposition, // 创建方式
  DWORD                 dwFlagsAndAttributes,  // 文件属性
  HANDLE                hTemplateFile   // 模板文件句柄
);

关键参数:

  • lpFileName: 要打开的文件的路径,"C:\\test\\myfile.txt"
  • dwDesiredAccess: 对于我们只想获取文件信息的情况,通常设置为 0GENERIC_READ
  • dwCreationDisposition: 我们只是打开一个已存在的文件,所以设置为 OPEN_EXISTING
  • dwFlagsAndAttributes: 通常设置为 FILE_ATTRIBUTE_NORMAL

CloseHandle

使用完文件句柄后,必须关闭它,以释放系统资源。

c语言 getfiletime
(图片来源网络,侵删)

函数原型:

BOOL CloseHandle(
  HANDLE hObject
);

完整代码示例

下面是一个完整的 C 语言程序,它会获取指定文件的创建时间、最后访问时间和最后修改时间,并将其转换为可读的格式。

#include <windows.h>
#include <stdio.h>
#include <tchar.h> // 为了使用 _tprintf 和 _T 宏,以便支持 Unicode
// 函数声明
void PrintFileTime(const FILETIME* ft);
int _tmain(int argc, _TCHAR* argv[]) {
    // 检查是否提供了文件名参数
    if (argc != 2) {
        _tprintf(_T("用法: %s <文件路径>\n"), argv[0]);
        return 1;
    }
    // 1. 使用 CreateFile 打开文件,获取句柄
    HANDLE hFile = CreateFile(
        argv[1],                  // 文件名
        GENERIC_READ,            // 读取权限
        FILE_SHARE_READ,          // 允许其他进程读取
        NULL,                    // 默认安全属性
        OPEN_EXISTING,           // 打开已存在的文件
        FILE_ATTRIBUTE_NORMAL,   // 普通文件
        NULL                     // 不使用模板文件
    );
    // 检查文件是否成功打开
    if (hFile == INVALID_HANDLE_VALUE) {
        _tprintf(_T("无法打开文件,错误代码: %d\n"), GetLastError());
        return 1;
    }
    // 2. 定义 FILETIME 结构体变量来接收时间
    FILETIME ftCreation, ftLastAccess, ftLastWrite;
    // 3. 调用 GetFileTime 获取文件时间
    if (GetFileTime(hFile, &ftCreation, &ftLastAccess, &ftLastWrite)) {
        _tprintf(_T("文件 '%s' 的时间信息:\n"), argv[1]);
        _tprintf(_T("--------------------------------\n"));
        _tprintf(_T("创建时间: "));
        PrintFileTime(&ftCreation);
        _tprintf(_T("最后访问时间: "));
        PrintFileTime(&ftLastAccess);
        _tprintf(_T("最后修改时间: "));
        PrintFileTime(&ftLastWrite);
    } else {
        _tprintf(_T("获取文件时间失败,错误代码: %d\n"), GetLastError());
    }
    // 4. 关闭文件句柄
    CloseHandle(hFile);
    return 0;
}
// 辅助函数:将 FILETIME 转换为可读的字符串并打印
void PrintFileTime(const FILETIME* ft) {
    // FILETIME 是 UTC 时间,我们需要将其转换为本地时间
    // 1. 先将 FILETIME 转换为 SYSTEMTIME
    SYSTEMTIME stUTC, stLocal;
    FileTimeToSystemTime(ft, &stUTC);
    SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
    // 2. 打印格式化的本地时间
    // 格式: YYYY-MM-DD HH:MM:SS
    _tprintf(_T("%04d-%02d-%02d %02d:%02d:%02d\n"),
             stLocal.wYear,
             stLocal.wMonth,
             stLocal.wDay,
             stLocal.wHour,
             stLocal.wMinute,
             stLocal.wSecond);
}

如何编译和运行

  1. 将上述代码保存为 getfiletime.c
  2. 打开 Visual Studio 的 "开发者命令提示" (Developer Command Prompt for VS)。
  3. 使用 cl.exe 编译代码:
    cl getfiletime.c
  4. 编译成功后,会生成 getfiletime.exe
  5. 运行程序,并传入一个文件路径作为参数,如果有一个 test.txt 文件在 C:\temp 目录下:
    getfiletime.exe "C:\temp\test.txt"

输出示例

文件 'C:\temp\test.txt' 的时间信息:
--------------------------------
创建时间: 2025-10-27 15:30:45
最后访问时间: 2025-10-27 15:35:10
最后修改时间: 2025-10-27 15:35:10
  1. 流程CreateFile -> GetFileTime -> CloseHandle,这个顺序不能乱。
  2. 句柄CreateFile 返回的句柄是后续所有操作的钥匙,必须妥善保管并在使用后关闭。
  3. 时间格式FILETIME 是一个 100 纳秒间隔的计数,不直观,通常需要使用 FileTimeToSystemTime 将其转换为 SYSTEMTIME 结构体,后者包含了年、月、日、时、分、秒等信息,更易于阅读和操作。
  4. 时区FileTimeToSystemTime 得到的是 UTC 时间,如果你想显示为本地时间,需要再调用 SystemTimeToTzSpecificLocalTime 进行转换,上面的示例代码已经包含了这一步。
  5. 错误处理:始终检查 CreateFileGetFileTime 的返回值,并在失败时使用 GetLastError() 获取错误原因,这对于调试至关重要。

跨平台注意事项

GetFileTimeWindows 特有的 API,如果你需要编写跨平台的 C 代码(在 Linux, macOS 等系统上也能运行),你需要使用标准 C 库或 POSIX 标准提供的函数,

  • Linux/macOS: 使用 stat 结构体和 stat() 函数。

    #include <sys/stat.h>
    #include <unistd.h>
    struct stat file_stat;
    if (stat("myfile.txt", &file_stat) == 0) {
        // st_mtime 是最后修改时间 (Unix timestamp)
        time_t last_modified = file_stat.st_mtime;
        // ...
    }

    POSIX 系统通常不提供文件的“创建时间”,只提供最后修改、最后访问和最后状态更改时间。

对于跨平台开发,通常会使用第三方库如 Boost.Filesystem 或 C++17 的 <filesystem> 库(C 语言中也可以通过一些封装来使用它们),它们会自动处理不同操作系统的差异。

-- 展开阅读全文 --
头像
织梦install dir
« 上一篇 01-03
关于笑话的dede模板免费下载
下一篇 » 01-03

相关文章

取消
微信二维码
支付宝二维码

目录[+]