一、概述
由于工作需要,需要使用Qt开发一套FTP工具,工具必须具备上传、下载、删除等基本功能。通过调研,基本有三种方式可以实现FTP功能。(1)QFTP:原来是Qt4的内置库,但是在Qt5的版本上被移除了,好在官网有源码,可以编译源码作为一个函数库使用,也可以将源码直接添加到工程里使用,总之看怎么方便怎么来。但是QFTP的缺点在于多级目录的操作上。例如删除操作,QFTP的rmdir()函数只能删除空文件夹,非空文件夹会报错。当然在源码的基础上可以修改源码实现多级目录的删除。此外在上传下载上如果是文件夹的情况也会出现问题。总之,QFTP在实现基础功能上是没有任何问题的,唯一的缺点在于多级目录。(2)QNetWorkAccessManager:目前Qt5支持的网络传输方式,可以实现FTP的操作,此外也会有上传、下载进度显示的信号机制。缺点在于无法实现文件删除、重命名、新建文件夹等操作,此外在上传和下载上也无法根据交互选择合适的地址。(3)Poco网络库:FTPClientSession是Poco库中用于FTP操作的类,可以实现上传、下载、重命名等一系列的操作,缺点在于下载、上传进度上没有具体的回调,需要自己计算数据大小算出精度,总之在显示上存在部分缺点。
鉴于我项目的需要,会存在文件(夹)的操作以及上传、下载功能,所以我采用的方案QFTP+FTPClientSession的方法,当然QNetWorkAccessManager我也用到了,只是后续为了尽量少的使用不同的方法将QNetWorkAccessManager的上传、下载用QFTP代替。我的方案是QFTP实现所有的功能,FTPClientSession只负责遍历文件列表,为QFTP提供操作地址。
二、基本功能
2.1 登陆、登出
此功能较为简单,就是将地址、端口、用户名和密码输入,然后login()即可。这里直接列出代码。三组信号槽函数对应FTP命令完成后的槽函数、list功能槽函数以及数据传输的进度槽函数。
bool FtpManager::connectToServer()
{
if (m_ftpFileManager == nullptr)
m_ftpFileManager = std::make_shared<QFtp>();
if (m_ftpFileManager->state() == QFtp::LoggedIn)
return false;
connect(m_ftpFileManager.get(), &QFtp::commandFinished, this, &FtpManager::on_ftpCommandFinished);
connect(m_ftpFileManager.get(), &QFtp::listInfo, this, &FtpManager::on_addFileToList);
connect(m_ftpFileManager.get(), &QFtp::dataTransferProgress, this, &FtpManager::uploadProgress);
m_ftpFileManager->connectToHost(m_pServerHost, m_pServerPort);
m_ftpFileManager->login(m_pServerUserNa