- 游戏开发
- 后端
【免费下载链接】kbengine
A MMOG engine of server.
本仓库(KBEngine,一个 MMOG 服务端引擎)在其
kbe/src/lib/python/目录下内嵌了完整的 CPython 标准库源码与文档,其中kbe/src/lib/python/Doc/library/stat.rst即为官方stat模块参考文档。本文以该文档为主体,结合内嵌的Lib/stat.py与 C 实现Modules/_stat.c,系统讲解stat模块的常量体系、文件类型判定函数、权限位、chflags 标志、Windows 文件属性常量,并给出贴近实际项目的实战示例——无论你是开发服务端工具脚本、资产扫描程序还是文件同步逻辑,都能从中掌握解读os.stat()返回结果的完整方法。
一、模块定位:为什么需要stat模块
在 Python 中,os.stat()、os.fstat()与os.lstat()(如果系统支持)返回一个包含文件元信息的 10 元组,其st_mode字段是一个位掩码(bitmask),同时编码了文件类型、权限位、setuid/setgid 位与粘滞位(sticky bit)。stat模块正是为解释这一原始位掩码而设计的标准库模块,它定义了两类核心内容:
- 常量:用于索引 10 元组各字段(
ST_MODE、ST_SIZE等),以及用于从st_mode中提取信息(S_IFMT、S_IMODE、S_IF*类型常量、S_I*权限常量等); - 函数:
S_ISDIR、S_ISREG等文件类型判定函数,以及filemode()格式化函数。
从版本演进看(文档.. versionchanged:: 3.4注明):自 Python 3.4 起,stat模块由 C 实现作为后盾——即优先从_stat扩展导入所有符号。本仓库内嵌的 kbe/src/lib/python/Lib/stat.py 第 174-178 行正是这一机制的体现:
# If available, use C implementation try: from _stat import * except ImportError: pass关于底层的stat、fstat、lstat系统调用语义,请查阅所在操作系统的手册;本文聚焦于 Python 层面的解释工具。
二、文件类型判定函数:S_IS*家族
文档定义了一组以S_IS开头的函数,用于判断mode(即st_mode)对应的文件类型,全部接受一个参数、返回非零值表示匹配:
| 函数 | 判定类型 | 说明 |
|---|---|---|
S_ISDIR(mode) | 目录 | 最常用的判定 |
S_ISCHR(mode) | 字符特殊设备文件 | 如终端、串口 |
S_ISBLK(mode) | 块特殊设备文件 | 如磁盘 |
S_ISREG(mode) | 普通文件 | 最常用的判定 |
S_ISFIFO(mode) | FIFO(命名管道) | |
S_ISLNK(mode) | 符号链接 | |
S_ISSOCK(mode) | 套接字 | |
S_ISDOOR(mode) | door(Solaris 专有) | 3.4 新增 |
S_ISPORT(mode) | event port(Solaris 专有) | 3.4 新增 |
S_ISWHT(mode) | whiteout(文件系统占位项) | 3.4 新增 |
这些函数在 kbe/src/lib/python/Lib/stat.py 中的实现模式完全一致,例如:
def S_ISDIR(mode): """Return True if mode is from a directory.""" return S_IFMT(mode) == S_IFDIR def S_ISREG(mode): """Return True if mode is from a regular file.""" return S_IFMT(mode) == S_IFREG而 C 实现 kbe/src/lib/python/Modules/_stat.c 为每个平台缺失的宏提供兜底定义(第 87-113 行),例如#ifndef S_ISBLK时定义S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK);对于不支持 door/port/whiteout 的平台,S_ISDOOR(mode)、S_ISPORT(mode)、S_ISWHT(mode)被定义为恒为 0 的宏,这正是文档注释所述"平台不支持时这些常量定义为 0"的落地实现。
使用时机建议(文档要点):常规场景下应优先使用os.path.is*系列函数(如os.path.isdir()、os.path.isfile())。S_IS*家族的优势在于:当需要对同一个文件做多次类型测试时,只需调用一次os.stat()拿到st_mode,即可反复判定,避免为每次测试重复发起stat系统调用;同时它还能覆盖os.path未处理的信息,例如块设备与字符设备的判定。文档给出的官方示例——递归遍历目录树并对每个普通文件回调,完整可运行:
import os, sys from stat import * def walktree(top, callback): '''recursively descend the directory tree rooted at top, calling the callback function for each regular file''' for f in os.listdir(top): pathname = os.path.join(top, f) mode = os.stat(pathname).st_mode if S_ISDIR(mode): # It's a directory, recurse into it walktree(pathname, callback) elif S_ISREG(mode): # It's a file, call the callback function callback(pathname) else: # Unknown file type, print a message print('Skipping %s' % pathname) def visitfile(file): print('visiting', file) if __name__ == '__main__': walktree(sys.argv[1], visitfile)三、通用模式操作:S_IMODE与S_IFMT
除类型判定外,文档还定义了两个更通用的位操作函数:
S_IMODE(mode):返回文件 mode 中可通过os.chmod()设置的部分——即权限位,外加粘滞位、set-group-id 与 set-user-id 位(在支持它们的系统上)。Lib/stat.py 中的实现为return mode & 0o7777,C 实现位于 Modules/_stat.c 第 318-327 行(mode & S_IMODE,其中S_IMODE默认定义为07777)。S_IFMT(mode):返回 mode 中描述文件类型的部分,即供S_IS*函数使用的类型掩码,实现为return mode & 0o170000。
四、filemode():把 mode 转成可读字符串
filemode(mode)自 Python 3.3 新增,将 mode 转换为形如-rwxrwxrwx的字符串;3.4 起支持S_IFDOOR、S_IFPORT、S_IFWHT(分别渲染为D、P、w)。
Python 版实现位于 Lib/stat.py 第 112-149 行,通过_filemode_table查表拼接;C 版stat_filemode位于 Modules/_stat.c 第 392-408 行,由两个子函数协作:
filetype()(第 346-364 行)输出首字符:普通文件-、目录d、符号链接l、块设备b、字符设备c、FIFOp、套接字s、doorD、event portP、whiteoutw,未知类型返回?;fileperm()(第 366-390 行)输出后 9 个权限字符,并处理特殊位的混合显示:当 setuid 位与执行位同时存在时显示小写s,仅有 setuid 位时显示大写S;setgid 同理;粘滞位与执行位并存显示t,仅粘滞位显示T。
一个典型调用:
>>> import os, stat >>> stat.filemode(os.stat("somefile").st_mode) '-rw-r--r--'五、10 元组索引常量:ST_*家族
os.stat()返回的 10 元组各字段可通过以下符号化索引常量访问(Lib/stat.py 第 8-17 行,取值与 C 结构struct stat的字段顺序一致):
| 常量 | 索引 | 含义 |
|---|---|---|
ST_MODE | 0 | inode 保护模式(即st_mode) |
ST_INO | 1 | inode 号 |
ST_DEV | 2 | inode 所在设备 |
ST_NLINK | 3 | inode 的链接数 |
ST_UID | 4 | 属主用户 ID |
ST_GID | 5 | 属主组 ID |
ST_SIZE | 6 | 普通文件字节数;部分特殊文件为等待读取的数据量 |
ST_ATIME | 7 | 最后访问时间 |
ST_MTIME | 8 | 最后修改时间 |
ST_CTIME | 9 | 操作系统报告的 "ctime":Unix 上多为元数据最后变更时间,Windows 上多为创建时间(详见平台文档) |
ST_SIZE的解释随文件类型变化(文档重点):普通文件即字节大小;大多数 Unix 变体(尤其 Linux)上,FIFO 与套接字的 "size" 表示调用os.stat()/os.fstat()/os.lstat()时等待读取的字节数,这对在非阻塞打开后轮询此类特殊文件非常有用;字符/块设备的 size 含义则随底层系统调用实现而异。仓库中 kbe/tools/xlsx2py/xlsx2py/xlsxtool.py 第 93 行os.stat(fileName)[-2]即通过ST_MTIME索引(索引 8,即倒数第二项)获取文件最后修改时间,用于判断 Excel 配置表是否需要重新转换——这是利用元组索引常量进行文件时效判断的典型工程实践。
六、文件类型掩码常量:S_IF*家族
以下常量定义了ST_MODE字段中用于标记文件类型的位掩码。文档同时提醒:优先使用上文S_IS*函数比直接使用这些掩码更可移植。数值定义可在 Lib/stat.py 第 36-42 行查到:
| 常量 | 八进制值 | 含义 |
|---|---|---|
S_IFDIR | 0o040000 | 目录 |
S_IFCHR | 0o020000 | 字符设备 |
S_IFBLK | 0o060000 | 块设备 |
S_IFREG | 0o100000 | 普通文件 |
S_IFIFO | 0o010000 | FIFO(命名管道) |
S_IFLNK | 0o120000 | 符号链接 |
S_IFSOCK | 0o140000 | 套接字 |
S_IFDOOR | 平台相关 | door(3.4 新增) |
S_IFPORT | 平台相关 | event port(3.4 新增) |
S_IFWHT | 平台相关 | whiteout(3.4 新增) |
注意文档的注记:当平台不支持相应文件类型时,S_IFDOOR、S_IFPORT、S_IFWHT均定义为 0。C 实现中这一逻辑体现在 Modules/_stat.c 第 70-80 行的条件宏定义(#ifndef S_IFDOOR时#define S_IFDOOR 0等)。
七、权限与特殊位常量:S_I*家族
以下常量可用于os.chmod()的mode参数(Lib/stat.py 第 76-94 行给出了全部八进制值):
| 常量 | 八进制值 | 含义 |
|---|---|---|
S_ISUID | 0o4000 | set UID 位 |
S_ISGID | 0o2000 | set-group-ID 位 |
S_ISVTX | 0o1000 | 粘滞位 |
S_IRWXU | 0o0700 | 属主权限掩码 |
S_IRUSR | 0o0400 | 属主可读 |
S_IWUSR | 0o0200 | 属主可写 |
S_IXUSR | 0o0100 | 属主可执行 |
S_IRWXG | 0o0070 | 组权限掩码 |
S_IRGRP | 0o0040 | 组可读 |
S_IWGRP | 0o0020 | 组可写 |
S_IXGRP | 0o0010 | 组可执行 |
S_IRWXO | 0o0007 | 其他用户权限掩码 |
S_IROTH | 0o0004 | 其他可读 |
S_IWOTH | 0o0002 | 其他可写 |
S_IXOTH | 0o0001 | 其他可执行 |
S_ENFMT | 0o2000 | System V 文件/记录锁强制(与S_ISGID共享位) |
S_IREAD | 0o0400 | Unix V7 中S_IRUSR的同义词 |
S_IWRITE | 0o0200 | Unix V7 中S_IWUSR的同义词 |
S_IEXEC | 0o0100 | Unix V7 中S_IXUSR的同义词 |
三个容易混淆的特殊位语义(文档重点展开):
S_ISGID:有多种特殊用途。对目录而言,它表示该目录采用 BSD 语义——在其中创建的文件继承目录的组 ID而非创建进程的有效组 ID,且在其中创建的目录也会自动设置S_ISGID;对未设置组执行位(S_IXGRP)的文件,该位表示强制文件/记录锁(见S_ENFMT)。S_ISVTX(粘滞位):设置于目录上时,目录中的文件只能被文件属主、目录属主或特权进程重命名或删除(典型的/tmp语义)。S_ENFMT:System V 文件锁定强制标志,与S_ISGID共享同一比特位——即对未设置组执行位的文件强制文件/记录锁。
八、chflags 标志:UF_*与SF_*家族
以下常量用于os.chflags()的flags参数,主要在 *BSD 与 macOS 系统上有效(完整数值见 Lib/stat.py 第 98-109 行):
| 常量 | 含义 |
|---|---|
UF_NODUMP | 不对文件执行 dump |
UF_IMMUTABLE | 文件不可更改 |
UF_APPEND | 文件只能追加写入 |
UF_OPAQUE | 通过 union stack 查看时目录为不透明 |
UF_NOUNLINK | 文件不可重命名或删除 |
UF_COMPRESSED | 文件压缩存储(macOS 10.6+) |
UF_HIDDEN | 文件不应在 GUI 中显示(macOS 10.5+) |
SF_ARCHIVED | 文件可被归档 |
SF_IMMUTABLE | 文件不可更改 |
SF_APPEND | 文件只能追加写入 |
SF_NOUNLINK | 文件不可重命名或删除 |
SF_SNAPSHOT | 文件是快照文件 |
其中UF_*为用户标志(superuser 可清),SF_*为系统标志(仅 superuser 可设/清)。更详细语义请参阅 *BSD 或 macOS 系统的chflags(2)手册页。
九、Windows 文件属性常量:FILE_ATTRIBUTE_*家族
在 Windows 上,os.stat()返回的st_file_attributes成员可用于测试以下文件属性常量(Python 3.5 起定义,数值见 Lib/stat.py 第 155-171 行;其 C 端定义见 Modules/_stat.c 顶部条件编译区):
FILE_ATTRIBUTE_ARCHIVE FILE_ATTRIBUTE_COMPRESSED FILE_ATTRIBUTE_DEVICE FILE_ATTRIBUTE_DIRECTORY FILE_ATTRIBUTE_ENCRYPTED FILE_ATTRIBUTE_HIDDEN FILE_ATTRIBUTE_INTEGRITY_STREAM FILE_ATTRIBUTE_NORMAL FILE_ATTRIBUTE_NOT_CONTENT_INDEXED FILE_ATTRIBUTE_NO_SCRUB_DATA FILE_ATTRIBUTE_OFFLINE FILE_ATTRIBUTE_READONLY FILE_ATTRIBUTE_REPARSE_POINT FILE_ATTRIBUTE_SPARSE_FILE FILE_ATTRIBUTE_SYSTEM FILE_ATTRIBUTE_TEMPORARY FILE_ATTRIBUTE_VIRTUAL示例(Windows 下判断只读与隐藏属性):
import os, stat attrs = os.stat("config.ini").st_file_attributes if attrs & stat.FILE_ATTRIBUTE_READONLY: print("read-only") if attrs & stat.FILE_ATTRIBUTE_HIDDEN: print("hidden")各常量的详细含义可参考 Windows API 文档(FILE_ATTRIBUTE_*常量说明)。
十、在 KBEngine 项目中的落地场景
KBEngine 仓库在 kbe/src/lib/python/ 目录下内嵌了完整的 CPython 标准库(含Lib/stat.py、Modules/_stat.c与本文对应的Doc/library/stat.rst文档),因此服务端与工具脚本可直接依赖标准stat模块。仓库内可观察到的典型实践包括:
- 文件修改时间判断:kbe/tools/xlsx2py/xlsx2py/xlsxtool.py 通过
os.stat(fileName)[-2](即ST_MTIME索引)获取 Excel 表最后修改时间,用于增量转换决策; - 目录遍历与文件分类:可使用第一节的
walktree模式对kbe/res/scripts/、kbe/res/sdk_templates/等资产目录做递归扫描,用S_ISDIR/S_ISREG区分目录与普通文件,跳过套接字、FIFO 等特殊文件; - 权限审计与部署检查:结合
S_IMODE与S_IRWXU/S_IRWXG/S_IRWXO校验可执行脚本(如kbe/res/sdk_templates/server/python_assets/下的.sh启动脚本)的权限位是否符合部署要求。
总结
stat模块是解读os.stat()系列返回值的事实标准工具。核心要点可归纳为四层:索引层(ST_*定位 10 元组字段)、提取层(S_IFMT/S_IMODE分离类型与权限位)、判定层(S_IS*完成类型测试)、展示层(filemode()输出-rwxrwxrwx形式字符串);另有两组平台相关标志(UF_*/SF_*用于 chflags,FILE_ATTRIBUTE_*用于 Windows 属性)。通过本仓库内嵌的 Lib/stat.py 与 Modules/_stat.c,你可以在阅读文档的同时直接对照每一处常量的数值定义与 C 级实现,从而在服务端工具、资产管理和部署脚本中写出既高效又可移植的文件元信息处理代码。
- 游戏开发
- 后端
【免费下载链接】kbengine
A MMOG engine of server.
相关推荐
Python stat 模块深度指南:解读 os.stat() 结果的文件类型、权限位与平台属性
Python stat 模块深度指南:解读 os.stat 结果的文件类型、权限位与平台属性 stat 是 CPython 标准库中用于解读 os.stat 、
编程语言语言运行时标准库解释器KBEngine 内嵌 Python 标准库 binhex 模块:BinHex4 编码与解码全解析
KBEngine 内嵌 Python 标准库 binhex 模块:BinHex4 编码与解码全解析 本指南以 KBEngine 仓库中内嵌的 CPython 3
游戏开发后端KBEngine 内嵌 Python 3.7.3 标准库 errno 模块详解:系统错误码字典与网络层错误判定实战
KBEngine 内嵌 Python 3.7.3 标准库 errno 模块详解:系统错误码字典与网络层错误判定实战 KBEngine 服务器端内嵌了一份完整的
游戏开发后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考