使用Paramiko编写SFTP脚本时遇OverflowError: mode out of range的解决咨询
解决Paramiko SFTP中stat.S_ISREG的OverflowError问题
问题背景
我正在编写SFTP脚本,需要遍历目录获取所有文件并排除子目录,但调用stat.S_ISREG时触发错误:
OverflowError: mode out of range
已知该错误是Paramiko处理服务器返回的st_mode时,比特位超过16位导致的。想知道解决方法,或者其他区分文件和目录的方式——曾考虑用st_mode > 34000判定文件夹,不确定是否正确。
相关代码
client_ssh = paramiko.SSHClient() client_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client_ssh.connect(host,username=user,password=pwd) sftp_client = client_ssh.open_sftp() df_file_info_sftp = pd.DataFrame([attr.__dict__ for attr in sftp_client.listdir_attr(directorio_remoto)]).sort_values("st_mtime", ascending=False) for row in df_file_info_sftp.itertuples(): print (row.filename) if stat.S_ISDIR(row.st_mode): print('Carpeta:') if stat.S_ISREG(row.st_mode): print('Archivo:' + row.filename) sftp_client.close client_ssh.close
解决方案
1. 修复st_mode的比特位问题(推荐)
Paramiko返回的st_mode可能包含额外的高位扩展信息,只需要用掩码保留低16位(标准Unix文件类型和权限位的范围),再传给stat函数即可:
for row in df_file_info_sftp.itertuples(): print(row.filename) # 用八进制掩码0o7777保留低16位有效信息 mode = row.st_mode & 0o7777 if stat.S_ISDIR(mode): print('Carpeta:') if stat.S_ISREG(mode): print('Archivo:' + row.filename)
Unix的文件类型和权限位都存储在低16位中,高位的扩展属性不影响文件类型判断,这个方法是最标准的修复方式。
2. 直接通过st_mode比特位判断文件类型
如果不想依赖stat模块,可以直接解析st_mode的文件类型位(Unix系统中,文件类型由st_mode的最高4位标识):
- 目录的类型标识位是
0o40000(八进制) - 普通文件的类型标识位是
0o100000(八进制)
代码示例:
for row in df_file_info_sftp.itertuples(): print(row.filename) # 提取文件类型位 file_type = row.st_mode & 0o170000 if file_type == 0o40000: print('Carpeta:') elif file_type == 0o100000: print('Archivo:' + row.filename)
3. 关于st_mode > 34000的判断方式
这种方法不可靠,不建议使用:
- 普通文件的st_mode可能超过34000(比如权限为0o777的普通文件,st_mode是0o100777,十进制为65535)
- 目录的st_mode也可能低于34000(比如权限为0o555的目录,st_mode是0o40555,十进制为20997)
会出现大量误判,无法准确区分文件和目录。
内容的提问来源于stack exchange,提问作者Duvan Chaves
相关产品推荐
相关产品推荐

