ftplib上传xml文件需用二进制模式(storbinary)并以rb方式打开文件,否则ascii模式会篡改换行符和高位字节导致乱码;还需注意权限、大小写、主动/被动模式及配套资源缺失等问题。

ftplib 上传 XML 文件时为什么文件内容变成乱码或损坏
因为 ftplib.FTP 默认用 ASCII 模式传输,而 XML 是文本但含 UTF-8 BOM、换行符、特殊字符(如 &、),ASCII 模式会悄悄修改换行符(CRLF ↔ LF)甚至截断高位字节,导致解析失败。
- 必须显式切换为二进制模式:
ftp.storbinary(),而不是ftp.storlines() - 本地 XML 文件需以
rb模式打开,确保原始字节不被 Python 文本编码层干扰 - 如果 XML 声明含
encoding="UTF-8",但文件实际带 BOM,FTP 本身不处理编码,靠你保证读写一致
Python ftplib 上传 XML 的最小可靠代码片段
以下代码绕过常见陷阱:不依赖默认编码、不假设路径存在、不忽略错误响应:
from ftplib import FTP
<p>ftp = FTP()
try:
ftp.connect('your-ftp-host', 21)
ftp.login('username', 'password')</p><h1>确保目标目录存在(FTP 不自动创建父目录)</h1><pre class='brush:php;toolbar:false;'>ftp.cwd('/upload/path')
with open('data.xml', 'rb') as f:
# 注意:storbinary 第二个参数是 file-like object,不是文件名
resp = ftp.storbinary('STOR data.xml', f)
print(resp) # 成功返回 '226 Transfer complete'finally: ftp.quit()
上传后 XML 在服务器上无法被解析的几个硬坑
FTP 传完了不代表能用——服务端环境常埋雷:
- 文件权限不对:
ftp.sendcmd('SITE CHMOD 644 data.xml')补一句,否则某些 Web 服务拒绝读取 - 路径大小写敏感:Linux 服务器上
Data.XML≠data.xml,XML 解析器报FileNotFoundError时先核对大小写 - FTP 主动/被动模式影响:内网或容器部署时,
ftp.set_pasv(True)(默认)可能被防火墙拦截,改False并确认主动端口开放 - XML 中的相对路径(如
<?xml-stylesheet type="text/xsl" href="style.xsl"?>)在服务器上失效,因 FTP 只传单文件,不传配套资源
比 ftplib 更稳的替代方案:用 ftputil 或 pysftp
ftplib 太底层,缺目录递归、自动编码适配、异常细分;真实项目里容易卡在边界问题上:
立即学习“Python免费学习笔记(深入)”;
-
ftputil封装了目录检查、文件存在判断:if not ftp_host.path.exists('/upload'),避免cwd报错中断 - 需要 SFTP(SSH)而非 FTP?直接换
pysftp,它默认二进制安全,且支持上下文管理器自动 close - 如果 XML 来自内存(非磁盘文件),
io.BytesIO(xml_bytes)可直接喂给storbinary,但注意别漏掉.seek(0)
真正麻烦的从来不是“怎么传”,而是“传完谁来验证它真能被下游系统加载”——建议上传后立刻用 ftp.retrlines('LIST data.xml') 检查大小是否匹配,再加一行 HTTP GET 或远程 curl 测试解析。










