PyInstaller打包单文件Python Windows应用,运行时无法读取捆绑数据文件怎么办?
解决PyInstaller单文件Windows应用读取捆绑数据文件的权限问题
问题根源
- 单文件模式下,PyInstaller会将所有资源解压到临时目录(由
sys._MEIPASS环境变量指向),而Path(__file__).parent获取的是临时exe的路径,并非资源文件所在的临时目录。 - Windows系统下,
stat.S_IWRITE/stat.S_IREAD这类Unix权限标志不适用,强行调用os.chmod会触发权限错误。
修正后的代码
替换原test.py的内容:
import os import sys from pathlib import Path # 获取PyInstaller临时解压目录 def get_bundle_dir(): if getattr(sys, 'frozen', False): # 打包后的运行环境 return Path(sys._MEIPASS) else: # 开发环境 return Path(__file__).parent / "data" bundle_dir = get_bundle_dir() file_path = bundle_dir / "data.txt" try: # 直接读取文件,无需修改权限 with open(file_path, "r", encoding="utf-8") as read_file: file_contents = read_file.read() print(f"文件内容:\n{file_contents}") except OSError as e: print(f"错误: {e.strerror}")
打包命令保持不变
继续使用原打包命令:
pyinstaller --onefile --add-data .\data\data.txt:. test.py
注:
--add-data的格式为源路径:目标路径,这里.表示将data.txt放到临时目录根目录,和代码中get_bundle_dir()的路径对应。
关键说明
sys._MEIPASS是PyInstaller为单文件模式专门设置的变量,指向资源文件的临时存放目录,仅在打包后的exe运行时存在。- 开发环境下,代码会自动读取原
data文件夹下的data.txt,方便调试。 - Windows系统下无需手动修改文件权限,临时目录中的捆绑文件默认拥有可读权限,之前的
os.chmod操作是多余且错误的。
内容的提问来源于stack exchange,提问作者Tom Archer
相关产品推荐
相关产品推荐

