Python FTP下载遇421超时错误:本地文件0字节求解决方案
问题分析与解决办法
核心原因
最关键的问题是RETR命令格式错误:你写的"RETR" + file会拼接成类似"RETRmysite_backup_01-Mar-2023.tgz"的字符串,FTP服务器无法识别这个非法命令,所以不会开始传输数据,连接长时间无交互就触发了421超时,本地自然只能生成0字节的空文件。
另外还有两个次要问题:
- 文件打开操作直接写在
retrbinary参数里,没有正确关闭文件的保障,可能导致资源泄漏 - 默认FTP超时时间可能偏短,即使命令正确,大文件传输也可能触发超时
解决建议
1. 修正RETR命令格式
在RETR和文件名之间必须加空格,这是FTP命令的语法要求:
ftp.retrbinary("RETR " + file, open("/home/PiEight/" + file, 'wb').write)
2. 优化文件写入逻辑
用with语句管理文件对象,确保文件自动关闭,避免资源泄漏:
with open(f"/home/PiEight/{file}", 'wb') as local_file: ftp.retrbinary(f"RETR {file}", local_file.write)
3. 延长FTP连接超时时间
初始化FTP对象时设置更长的超时时间(比如300秒),适配大文件传输的需求:
ftp = FTP('ftp.mydomain.com', timeout=300)
4. 增强错误处理
捕获更多FTP相关异常,方便排查其他潜在问题:
from ftplib import FTP, error_perm, error_temp # ... try: with open(f"/home/PiEight/{file}", 'wb') as local_file: ftp.retrbinary(f"RETR {file}", local_file.write) print(f"Successfully downloaded {file}") except error_perm as e: print(f"Permission error when downloading {file}: {e}") except error_temp as e: print(f"Temporary error when downloading {file}: {e}") except Exception as e: print(f"Unexpected error: {e}")
修正后的完整脚本
from ftplib import FTP, error_perm, error_temp import fnmatch # 初始化FTP连接,设置超时时间 ftp = FTP('ftp.mydomain.com', timeout=300) ftp.login('websitebackups@mydomain.com', 'mypassword') files = ftp.nlst() for file in files: if fnmatch.fnmatch(file, '*tgz'): print(f"Downloading...{file}") try: with open(f"/home/PiEight/{file}", 'wb') as local_file: ftp.retrbinary(f"RETR {file}", local_file.write) print(f"Download completed: {file}") except error_perm as e: print(f"Permission denied: {e}") except error_temp as e: print(f"Timeout or temporary error: {e}") except Exception as e: print(f"Error downloading {file}: {e}") ftp.close()
内容的提问来源于stack exchange,提问作者Ken
相关产品推荐
相关产品推荐

