一、_stat结构体中存储了Windows文件系统的信息
struct _stat
是Windows平台用于存储文件系统元数据的核心数据结构,它提供了文件的完整"指纹"信息。当我们调用_stat()
函数时,系统会填充这个结构体,使其包含从底层文件系统获取的所有关键信息。
struct _stat {
_dev_t st_dev; // 包含文件的设备标识符
_ino_t st_ino; // 文件索引号(Windows通常为0)
unsigned short st_mode; // 文件模式和属性(核心字段)
short st_nlink; // 硬链接数量
short st_uid; // 用户ID(Windows未使用)
short st_gid; // 组ID(Windows未使用)
_dev_t st_rdev; // 设备ID(特殊文件)
_off_t st_size; // 文件大小(字节)
time_t st_atime; // 最后访问时间
time_t st_mtime; // 最后修改时间
time_t st_ctime; // 文件创建时间
};
二、关键字段深度解析
1. st_mode:文件类型与属性的二进制掩码
unsigned short st_mode; // 16位标志位
位掩码定义:
#define _S_IFMT 0xF000 // 文件类型掩码
#define _S_IFDIR 0x4000 // 目录
#define _S_IFCHR 0x2000 // 字符设备
#define _S_IFIFO 0x1000 // FIFO/管道
#define _S_IFREG 0x8000 // 普通文件
// Windows特有属性
#define _S_IREAD 0x0100 // 读权限
#define _S_IWRITE 0x0080 // 写权限
#define _S_IEXEC 0x0040 // 执行权限
例子(已封装成了函数):
void printFileInfo(const char* path)
{
// 初始化为0
struct _stat info = { 0 };
// 获取文件信息
if (_stat(path, &info) != 0)
{
// 可能是文件不存在
print("文件状态获取失败: %s\n", path);
return;
}
// 1. 基本文件信息
print("文件路径: %s\n", path);
// 权限掩码值
print("权限掩码值: 0x%04X\n", info.st_mode);
// 2. 文件类型和权限
print("\n文件类型与权限:\n");
print("--------------------\n");
// 文件类型
// #define _S_IFMT 0xF000 // File type mask文件类型掩码
// #define _S_IFDIR 0x4000 // Directory目录类型
// #define _S_IFCHR 0x2000 // Character special字符设备文件
// #define _S_IFIFO 0x1000 // Pipe命名管道或FIFO
// #define _S_IFREG 0x8000 // Regular普通文件
print("文件类型: ");
if (info.st_mode & _S_IFDIR) print("目录\n");
else if (info.st_mode & _S_IFREG) print("普通文件\n");
else if (info.st_mode & _S_IFCHR) print("字符设备\n");
else if (info.st_mode & _S_IFIFO) print("管道/FIFO\n");
else print("未知类型\n");
// 文件权限
// #define _S_IREAD 0x0100 // Read permission, owner读权限标志(所有者可读)
// #define _S_IWRITE 0x0080 // Write permission, owner写权限标志(所有者可写)
// #define _S_IEXEC 0x0040 // Execute/search permission, owner执行权限标志(所有者可执行/搜索)
print("权限: ");
if (info.st_mode & _S_IREAD) print("读取 ");
if (info.st_mode & _S_IWRITE) print("写入 ");
if (info.st_mode & _S_IEXEC) print("执行");
print("\n");
// 3. 文件大小信息
print("\n大小信息:\n");
print("-----------------\n");
print("大小: %lld 字节\n", (long long)info.st_size);
// 4. 标识符信息
print("\n标识信息:\n");
print("------------\n");
print("设备ID: %d\n", info.st_dev);
print("关联设备ID: %d\n", info.st_rdev);
print("索引节点号: %lld\n", (long long)info.st_ino);
print("硬链接数: %d\n", info.st_nlink);
// 8. 时间戳原始值
print("\n原始时间戳值 (1970-01-01 UTC起秒数):\n");
print("------------------------------------\n");
print("访问时间: %lld\n", (long long)info.st_atime);
print("修改时间: %lld\n", (long long)info.st_mtime);
print("创建时间: %lld\n", (long long)info.st_ctime);
// 6. 时间信息
print("\n格式化时间:\n");
struct tm* atime = localtime(&info.st_atime);
struct tm* mtime = localtime(&info.st_mtime);
struct tm* ctime = localtime(&info.st_ctime);
print("访问时间: %04d-%02d-%02d %02d:%02d:%02d\n",
atime->tm_year + 1900, atime->tm_mon + 1, atime->tm_mday,
atime->tm_hour, atime->tm_min, atime->tm_sec);
print("修改时间: %04d-%02d-%02d %02d:%02d:%02d\n",
mtime->tm_year + 1900, mtime->tm_mon + 1, mtime->tm_mday,
mtime->tm_hour, mtime->tm_min, mtime->tm_sec);
print("创建时间: %04d-%02d-%02d %02d:%02d:%02d\n",
ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday,
ctime->tm_hour, ctime->tm_min, ctime->tm_sec);
}
//封装函数中的print是另一个封装函数,自己谢谢
printFileInfo(“C:\Windows”);
printFileInfo(“C:\Windows\notepad.exe”);
效果
3. 大小与存储信息
_off_t st_size; // 文件大小(字节)
- 32位系统限制:最大2GB(使用_stat64处理大文件)
- 目录大小:通常返回0或文件系统块大小
- 实际占用:需结合
st_blocks
和st_blksize
计算
大文件处理:
struct _stat64 info64;
if (_stat64("large_file.dat", &info64) == 0) {
printf("文件大小: %.2f GB\n",
(double)info64.st_size / (1024*1024*1024));
}
三、_stat()函数:获取文件信息的桥梁
函数原型:
int _stat(const char* path, struct _stat* buffer);
参数解析:
参数 | 类型 | 说明 |
---|---|---|
path | const char* | 目标路径(ANSI编码) |
buffer | struct _stat* | 接收文件状态的结构体指针 |
返回值:
0
:成功-1
:失败
四、推荐替代
- 新项目:C++17 Filesystem库
- 高性能需求:直接Windows API(GetFileAttributesEx)