FTP上传XML文件 Java/Python脚本如何实现
技术百科
煙雲
发布时间:2026-01-21
浏览: 次 最稳妥方案是Java用Apache Commons Net的FTPClient以二进制模式上传XML。需设FTP.BINARY_FILE_TYPE、UTF-8编码、被动模式,并校验文件大小或哈希,避免换行符损坏和乱码。
Java用Apache Commons Net实现FTP上传XML文件
Java里最稳妥的方案是用 org.apache.commons.net.ftp.FTPClient,它对二进制传输、编码、被动模式支持完整,避免XML文件因换行符或UTF-8 BOM被截断或乱码。
关键点在于:XML必须以 FTP.BINARY_FILE_TYPE 上传,否则ASCII模式会把 \r\n 转成 \n,破坏XML结构;同时要显式设置客户端编码为 UTF-8,否则文件名含中文时可能失败。
- 调用
ftpClient.setFileType(FTP.BINARY_FILE_TYPE),别依赖默认值 - 连接后立即执行
ftpClient.setControlEncoding("UTF-8") - 启用被动模式:
ftpClient.enterLocalPassiveMode(),否则内网/容器环境大概率超时 - 上传前检查目标路径是否存在,
ftpClient.changeWorkingDirectory("/upload")失败时不抛异常,需手动判断返回值
FTPClient ftp = new FTPClient();
ftp.connect("ftp.example.com", 21);
ftp.login("user", "pass");
ftp.setControlEncoding("UTF-8");
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.enterLocalPassiveMode();
if (!ftp.changeWorkingDirectory("/xml")) {
throw new IOException("Target dir /xml not found");
}
try (InputStream is = Files.newInputStream(Paths.get("data.xml"))) {
ftp.storeFile("report_2025.xml", is);
}
Python用ftplib上传XML注意换行与编码
ftplib.FTP 默认用 ASCII 模式传文件,直接 storbinary() 传XML没问题,但若用 storlines() 就会出事——它按行读取并替换换行符,导致XML声明 后面的 \n 被改写,解析器报错 ParseError: mismatched tag。
- 一律用
storbinary(),哪怕文件是纯文本 - 打开本地XML文件必须用
rb模式,不能用r,否则Windows下 \r\n 可能被Python自动转换 - 如果XML含中文且服务器文件系统是GBK(如老版Windows Server),上传后需在服务端用 iconv 转码,Python侧无法干预
- 建议上传前先
ftp.pwd()确认当前路径,避免因路径错误静默失败
from ftplib import FTP
ftp = FTP()
ftp.connect("ftp.example.com", 21)
ftp.login("user", "pass")
ftp.cwd("/xml")
with open("config.xml", "rb") as f:
ftp.storbinary("STOR config_v2.xml", f)
ftp.quit()
上传后校验XML是否完整可用
FTP协议不保证传输完整性,网络抖动或服务器磁盘满时,可能只写入部分字节,而 storeFile() 或 storbinary() 仍返回成功。XML文件一旦缺失结束标签或属性引号,下游系统解析直接崩溃。
- 上传后立刻用
ftp.size("file.xml")对比本地os.path.getsize(),大小不等说明传输中断 - 更可靠的做法:上传后用
ftp.retrbinary()下载回来,做SHA256哈希比对(适合小文件) - 不要依赖FTP服务器日志——很多共享主机不记录具体文件操作,且日志延迟高
- 如果下游是Java系统,可加一步远程执行
xmllint --noout file.xml(需服务器装libxml2),但需额外SSH权限

为什么不用SFTP替代FTP?
因为很多政务、银行老系统只开放FTP端口(21),禁用SSH(22),且明确要求XML必须用明文FTP上传。强行上SFTP会卡在合规审批环节。但要注意:FTP密码和XML内容都在明文传输,如果中间有Wireshark抓包,敏感字段(如身份证、金额)会裸奔。
- XML中敏感字段必须提前AES加密,再base64编码,不能靠FTP“安全”
- 测试环境可用
vsftpd搭本地FTP,配置pasv_min_port=50000和pasv_max_port=50010,避免端口随机导致防火墙放行困难 - Java用
FTPClient时,若遇到java.net.SocketTimeoutException: Read timed out,大概率是被动模式端口没通,不是代码问题
FTP上传XML真正难的不是写几行代码,而是确认对方FTP服务器的字符集、目录权限、被动端口范围、以及是否悄悄启用了FTP over TLS(即FTPS)。这些信息不问清楚,光调通本地脚本没用。
# 就会
# 会把
# 都在
# 但要
# python
# windows
# 上传
# 时要
# 它对
# win
# 防火墙
# 端口
# ssh
# java
# 编码
# 字节
# stream
# xml
# 报错
# bom
# ASCII
# apache
# 不能用
# python脚本
# 换行符
# wireshark
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- MAC如何启用访达侧边栏显示_MAC Finder
- 如何使用Golang反射创建map对象_动态生成键
- Python路径拼接规范_跨平台处理说明【指导】
- LINUX怎么进行文本内容搜索_Linux gre
- 如何使用Golang encoding/json解
- Python网络异常模拟_测试说明【指导】
- Windows怎样关闭开始菜单广告_Windows
- C++中的std::shared_from_thi
- 如何在Golang中验证模块完整性_Golangg
- Windows蓝屏错误0x00000018怎么处理
- Python文件和流处理指南_高效读写大体积数据文
- Win11怎么关闭通知消息_屏蔽Windows 1
- Python代码测试策略_质量保障解析【教程】
- 如何在包含多值的列中精准搜索指定演员?
- Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱
- 如何优化Golang Web性能_Golang H
- Go 中 defer 在 goroutine 内部
- Win11怎么清理C盘下载文件夹_Win11清理下
- Python安全爬虫设计_IP代理池与验证码识别策
- Win11怎么连接蓝牙耳机_Win11蓝牙设备配对
- 如何在Golang中处理模块冲突_解决依赖版本不兼
- Mac如何开启夜览模式_Mac护眼模式设置与定时
- Win11怎么关闭搜索历史_Win11清除任务栏搜
- 如何优化Golang程序CPU性能_Golang
- c++如何判断文件是否存在_c++ filesys
- Win10怎样设置闹钟贪睡时间 Win10闹钟贪睡
- Mac怎么开启“任何来源”_Mac安装未签名应用的
- Win10电脑怎么设置网络名称_Windows10
- Mac的Time Machine怎么用_Mac系统
- Win10怎样卸载TeamViewer_Win10
- Win11怎么关闭粘滞键_彻底禁用Windows
- 如何在 Go 中判断变量是否为函数类型
- PowerShell怎么创建复杂的XML结构
- Windows驱动无法加载错误解决方法_驱动签名验
- 如何使用Golang实现跨域请求支持_Golang
- php下载安装后memory_limit怎么设置_
- PHP主流架构怎么监控运行状态_工具推荐【操作】
- Linux如何安装JDK11_Linux环境变量配
- Win11应用商店下载慢怎么办 Win11更改DN
- Go 语言标准库为何不提供泛型 Contains
- 如何在 Windows 11 中使用 AlomWa
- 如何使用Golang实现Web表单数据绑定_自动映
- Win11怎么硬盘分区 Win11新建磁盘分区详细
- Win11键盘快捷键大全_Windows 11常用
- Win10闹钟铃声怎么自定义 Win10闹钟自定义
- Windows10系统怎么查看硬盘健康_Win10
- mac怎么安装adb_MAC配置Android A
- MAC怎么用连续互通相机里的“桌上视角”_MAC在
- php打包exe如何加密代码_防反编译保护方法【技
- php8.4新语法match怎么用_php8.4m

QQ客服