FtpWebRequest上传失败主因是未设Credentials或EnableSsl不匹配;下载大文件需流式读写防OOM;目录列表必须用ListDirectoryDetails并正确解析;.NET 6+已弃用但无替代,建议用FluentFTP或抑制警告。

用 FtpWebRequest 上传文件时连不上,大概率是没设 Credentials 或协议没关对
FTP 在 .NET 中默认走明文,但很多服务器(尤其是启用了 FTPS 的)会拒绝未认证或未显式指定协议的连接。不设 Credentials 会直接抛 WebException: The remote server returned an error: (530) Not logged in.;而没关 EnableSsl 却连着支持 SSL 的服务器,会卡在握手阶段,超时后报 Unable to connect to the remote server。
- 必须显式设置
request.Credentials = new NetworkCredential("user", "pass"),匿名登录也不能省略——得用new NetworkCredential("", "") - 如果服务器要求 FTPS(隐式或显式),需同时设
request.EnableSsl = true,且request.Proxy = null(代理常干扰 SSL 握手) - 注意端口:普通 FTP 默认 21,FTPS 显式模式仍是 21,隐式 FTPS 通常是 990——端口号要和
EnableSsl匹配,否则连都连不上
FtpWebRequest 下载大文件容易卡死或内存爆掉,因为默认把整个响应流读进内存
FtpWebRequest.GetResponse() 返回的 Stream 是可读的,但很多人直接用 ReadAllBytes() 或 StreamReader.ReadToEnd(),一下载几百 MB 文件就 OOM。这不是 bug,是设计使然:它不提供分块缓冲机制,全靠你自己控制读取节奏。
- 下载时务必用
response.GetResponseStream()+FileStream配合固定大小 buffer(比如 8192 字节),边读边写,别碰任何“一次性读完”的方法 - 记得在
finally块里调用response.Close()和stream.Close(),否则连接不释放,很快触发The remote server returned an error: (425) Can't open data connection. - 如果文件路径含中文或特殊字符,
request.RequestUri必须是已 URL 编码的,否则服务器返回 550 错误,但错误信息里不会提示编码问题
列出目录用 WebRequestMethods.Ftp.ListDirectoryDetails,别用 ListDirectory
ListDirectory 只返回文件名列表,格式依赖服务器实现(Unix 风格?DOS 风格?),根本没法解析权限、时间、大小。而 ListDirectoryDetails 返回标准 UNIX ls -la 格式(即使 Windows FTP 服务器也模拟),字段顺序稳定,能可靠提取关键信息。
- 解析时按行 split,每行开头是
drwxr-xr-x这类权限字符串,后面跟着硬链接数、所有者、组、大小、月、日、年/时间、文件名 - 注意年份字段可能被替换成时间(比如
Jan 15 10:23),需判断第 7 字段是否为数字来区分“年”还是“时间” - 别用正则硬匹配整行——不同服务器空格数量不一致,用
string.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries)更稳
.NET 6+ 项目里 FtpWebRequest 已被标记为 obsolete,但暂时没替代方案
微软在 .NET 6 中把 FtpWebRequest 标为 Obsolete("FtpWebRequest is obsolete."),但至今没提供官方替代品。社区主流做法仍是继续用它,只是加个 #pragma warning disable SYSLIB0014 抑制警告。
- 别指望
HttpClient能干 FTP 的活——它根本不支持 FTP 协议,连构造ftp://URI 都会报错 - 第三方库如
FluentFTP功能强、支持断点续传和 UTF-8 路径,但引入新依赖意味着多一个攻击面和兼容性风险,内部工具脚本慎选 - 真正麻烦的是 FTP 主动模式(Active Mode)在 NAT/防火墙后基本不可用,而
FtpWebRequest不支持设置 PASV 模式开关——它内部自动协商,但失败时只报模糊的 425 错误,很难定位是网络策略还是代码问题
FTP 协议本身的歧义性和服务器实现差异,比代码逻辑更难调试。路径斜杠方向、编码、模式切换、连接复用……这些细节不出问题时感觉不到,一出就是连环故障。











