os.listdir()和glob.glob()默认看不到Windows隐藏文件,是因为它们底层调用Win32 API的FindFirstFile,该函数默认过滤掉带FILE_ATTRIBUTE_HIDDEN标志的条目,并非Python主动忽略。

为什么 os.listdir() 和 glob.glob() 默认看不到隐藏文件
Windows 的“隐藏”属性(Hidden attribute)是文件系统级标记,和 Unix 的点文件(.gitignore)机制完全不同。os.listdir()、pathlib.Path.iterdir()、glob.glob() 等 Python 标准库函数默认调用的是 Win32 API 中的 FindFirstFile,而它默认**过滤掉带 FILE_ATTRIBUTE_HIDDEN 标志的条目**——不是 Python 故意忽略,是底层 Windows 行为。
用 win32api 获取带隐藏属性的文件列表
最直接的方式是调用 Win32 原生 API。需要安装 pywin32:pip install pywin32。关键函数是 win32api.FindFiles(),它返回完整属性信息,不做过滤:
import win32api
import win32con
<p>def list_hidden_files(directory):
files = win32api.FindFiles(f"{directory}\<em>.</em>")
for f in files:
attr = f[1] # 第二项是属性值
if attr & win32con.FILE_ATTRIBUTE_HIDDEN:
print(f[0]) # 文件名</p><p>list_hidden_files(r"C:\Users\Me")
-
f[1]是文件属性整数,需按位与win32con.FILE_ATTRIBUTE_HIDDEN判断 - 该方法能同时识别系统文件(
FILE_ATTRIBUTE_SYSTEM)、只读、目录等,适合做精细筛选 - 注意路径末尾加
\*.*,否则FindFiles报错
用 ctypes 调用 FindFirstFileW(免第三方依赖)
如果不想引入 pywin32,可用 ctypes 直接调用 Windows SDK 的 FindFirstFileW。核心是传入 INVALID_FILE_ATTRIBUTES 作为搜索条件,并检查返回结构体中的 dwFileAttributes 字段:
import ctypes
from ctypes import wintypes
<p>kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
INVALID_HANDLE_VALUE = -1</p><p>class WIN32_FIND_DATAW(ctypes.Structure):
<em>fields</em> = [
("dwFileAttributes", wintypes.DWORD),
("ftCreationTime", wintypes.FILETIME),
("ftLastAccessTime", wintypes.FILETIME),
("ftLastWriteTime", wintypes.FILETIME),
("nFileSizeHigh", wintypes.DWORD),
("nFileSizeLow", wintypes.DWORD),
("dwReserved0", wintypes.DWORD),
("dwReserved1", wintypes.DWORD),
("cFileName", wintypes.WCHAR <em> 260),
("cAlternateFileName", wintypes.WCHAR </em> 14),
]</p><p>def list_hidden_with_ctypes(path):
find_data = WIN32_FIND_DATAW()
handle = kernel32.FindFirstFileW(f"{path}\<em>.</em>", ctypes.byref(find_data))
if handle == INVALID_HANDLE_VALUE:
return
try:
while True:
if find_data.dwFileAttributes & 0x04: # FILE_ATTRIBUTE_HIDDEN == 4
print(find_data.cFileName)
if not kernel32.FindNextFileW(handle, ctypes.byref(find_data)):
break
finally:
kernel32.FindClose(handle)
-
0x04是FILE_ATTRIBUTE_HIDDEN的十六进制值,硬编码更轻量 - 必须手动调用
FindClose,否则句柄泄漏 - 该方式不依赖外部包,但代码更底层,出错时错误信息不友好
用 subprocess 调用 dir /a:h(简单但有局限)
命令行 dir /a:h 可列出隐藏文件,用 subprocess 捕获输出是最省事的方案,适合一次性脚本:
立即学习“Python免费学习笔记(深入)”;
import subprocess <p>result = subprocess.run( ["cmd", "/c", "dir", "/a:h", "/b", "C:\Users\Me"], capture_output=True, text=True, encoding="gbk" # 注意 Windows 控制台默认编码通常是 gbk 或 cp936 ) if result.returncode == 0: for line in result.stdout.strip().splitlines(): print(line)
-
/a:h表示仅显示属性含 Hidden 的文件;/b是简洁格式(无头信息) - 编码必须匹配当前控制台(
chcp查看),常见是gbk,非utf-8 - 无法获取文件大小、时间等元数据,纯文本解析也容易受空行或中文路径干扰
真正麻烦的不是“怎么读”,而是“怎么安全地判断隐藏属性”——Windows 还有“系统 + 隐藏”“只读 + 隐藏”组合,且某些路径(如 C:\$Recycle.Bin)即使有权限也可能被跳过。用 win32api 或 ctypes 才能拿到原始属性位,其他方式都只是间接推断。


















