关于Qt **QNetworkAccessManager**、**QNetworkReply**、**QNetworkRequest**实现ftp下载时,**QNetworkReply**::**downloadProgress**信号的**bytesTotal**一直为-1的原因分析
实现的ftp下载需要反馈下载进度,但是代码得到的bytesTotal始终为-1,直到下载完成那一刻,才变成文件大小。于是分析qt5base的network部分代码:
network/access/qnetworkaccessftpbackend.cpp文件中,有如下片段:
void QNetworkAccessFtpBackend::ftpRawCommandReply(int code, const QString &text) { //qDebug() << "FTP reply:" << code << text; int id = ftp->currentId(); if ((id == helpId) && ((code == 200) || (code == 214))) { // supported commands // the "FEAT" ftp command would be nice here, but it is not part of the // initial FTP RFC 959, neither ar "SIZE" nor "MDTM" (they are all specified // in RFC 3659) if (text.contains(QLatin1String("SIZE"), Qt::CaseSensitive)) supportsSize = true; if (text.contains(QLatin1String("MDTM"), Qt::CaseSensitive)) supportsMdtm = true; if (text.contains(QLatin1String("PWD"), Qt::CaseSensitive)) supportsPwd = true; } else if (id == pwdId && code == 257) { QString pwdPath; int startIndex = text.indexOf('"'); int stopIndex = text.lastIndexOf('"'); if (stopIndex - startIndex) { // The working directory is a substring between \" symbols. startIndex++; // skip the first \" symbol pwdPath = text.mid(startIndex, stopIndex - startIndex); } else { // If there is no or only one \" symbol, use all the characters of // text. pwdPath = text; }
此处它通过SITE help命令查询ftp server支持的命令,我这边ftp server是pureftpd,实际在终端用ftp命令连接上后,site help查询得到的结果确实没有SIZE的支持,尝试通过配置文件看能否打开此命令的支持,但是每查到,于是阅读pureftpd源码,src/ftp_parser.c
中可知,site help
得到的返回永远是固定的,
else if (!strcasecmp(arg, "help")) { help_site: addreply_noformat(214, MSG_SITE_HELP CRLF # ifdef WITH_DIRALIASES " ALIAS" CRLF # endif " CHMOD" CRLF " IDLE" CRLF " UTIME"); addreply_noformat(214, "Pure-FTPd - http://pureftpd.org/"); }
于是只好暴力修改Qt源码,QNetworkAccessFtpBackend构造的初始化列表将
QNetworkAccessFtpBackend::QNetworkAccessFtpBackend() : ftp(nullptr), uploadDevice(nullptr), totalBytes(0), helpId(-1), sizeId(-1), mdtmId(-1), pwdId(-1), supportsSize(true), supportsMdtm(false), supportsPwd(false), state(Idle) { }
supportsSize(false) 改为true.问题解决,不过对应的ftp server那端必须要支持size命令,好在ftp server大多一般都支持size。解决方案不优雅,但是可行。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具