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

(图片来源网络,侵删)
核心概念
- 文件时间:在 Windows 中,文件时间不是我们通常使用的
struct tm(年、月、日、时、分、秒),而是从 1601 年 1 月 1 日 UTC (协调世界时) 开始的 100 纳秒间隔数,这是一个 64 位整数,类型是FILETIME。 FILETIME结构体:typedef struct _FILETIME { DWORD dwLowDateTime; // 低32位 DWORD dwHighDateTime; // 高32位 } FILETIME;- 三种时间:
- 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。
返回值:

(图片来源网络,侵删)
- 成功返回
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: 对于我们只想获取文件信息的情况,通常设置为0或GENERIC_READ。dwCreationDisposition: 我们只是打开一个已存在的文件,所以设置为OPEN_EXISTING。dwFlagsAndAttributes: 通常设置为FILE_ATTRIBUTE_NORMAL。
CloseHandle
使用完文件句柄后,必须关闭它,以释放系统资源。

(图片来源网络,侵删)
函数原型:
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);
}
如何编译和运行
- 将上述代码保存为
getfiletime.c。 - 打开 Visual Studio 的 "开发者命令提示" (Developer Command Prompt for VS)。
- 使用 cl.exe 编译代码:
cl getfiletime.c
- 编译成功后,会生成
getfiletime.exe。 - 运行程序,并传入一个文件路径作为参数,如果有一个
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
- 流程:
CreateFile->GetFileTime->CloseHandle,这个顺序不能乱。 - 句柄:
CreateFile返回的句柄是后续所有操作的钥匙,必须妥善保管并在使用后关闭。 - 时间格式:
FILETIME是一个 100 纳秒间隔的计数,不直观,通常需要使用FileTimeToSystemTime将其转换为SYSTEMTIME结构体,后者包含了年、月、日、时、分、秒等信息,更易于阅读和操作。 - 时区:
FileTimeToSystemTime得到的是 UTC 时间,如果你想显示为本地时间,需要再调用SystemTimeToTzSpecificLocalTime进行转换,上面的示例代码已经包含了这一步。 - 错误处理:始终检查
CreateFile和GetFileTime的返回值,并在失败时使用GetLastError()获取错误原因,这对于调试至关重要。
跨平台注意事项
GetFileTime 是 Windows 特有的 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 语言中也可以通过一些封装来使用它们),它们会自动处理不同操作系统的差异。
