Go标准库无FTP客户端支持,需用github.com/jlaffaye/ftp;其自动处理PASV模式、MLSD解析与UTF-8协商,但上传下载必须显式Close()以确保传输完成,且中文路径需OPTS UTF8 ON启用。
Go 标准库不提供 FTP 客户端支持,net/ftp 不存在 —— 这是开发者踩坑的第一步。必须依赖第三方库,而当前最稳定、维护活跃、API 清晰的是 github.com/jlaffaye/ftp。
为什么不能用标准库的 net 包直接连 FTP
FTP 协议本身有控制连接(命令通道)和数据连接(传输通道)两路,且数据连接模式(主动/被动)需协商,还涉及 PORT/PASV 命令解析、端口动态分配、防火墙兼容等细节。标准库的 net 只提供底层 TCP/UDP 能力,没封装任何 FTP 状态机或命令序列逻辑。
常见错误现象:read tcp: i/o timeout 或 500 Illegal PORT command,基本都源于手动拼接 FTP 命令时忽略状态同步或 PASV 解析失败。
- 不要尝试用
net.Dial+ 手写USER/PASS序列 —— 控制流、编码(如空格转义)、响应码判断、多行响应处理全得自己实现 -
github.com/jlaffaye/ftp内置了完整的 RFC 959 兼容实现,自动处理 PASV 模式切换、MLSD 列表解析、UTF-8 文件名协商(需显式启用) - 该库默认使用被动模式(PASV),对 NAT/客户端防火墙友好;如需主动模式,需调用
Conn.ActiveMode()并确保客户端开放高位端口
如何安全登录并列出远程目录(含中文路径)
FTP 登录本身不加密,密码明文传输。若服务端未启用 FTPS(即 FTP over TLS),敏感环境应避免生产使用;但开发调试或内网场景下,可先聚焦功能实现。