当前位置:网站首页>QNetworkAccessManager实现ftp功能总结
QNetworkAccessManager实现ftp功能总结
2022-07-06 09:28:00 【Larry_Yanan】
因为项目需要,第一次接触到FTP的上传问题,经过查阅后摈弃了旧的QFtp,采用新的QNetworkAccessManager。有关它的使用其实也很方便,已经提供了比较成熟的接口和信号,下面总结一下。
首先,在头文件创建一些变量和指针
QUrl url;
QNetworkAccessManager *accessManager; //初始化为nullptr
QNetworkReply *reply; //初始化为nullptr
QFile *ftp_file; //初始化为nullptr
bool ftp_upload = false; //上传文件标识
bool ftp_download = false; //上传文件标识
url是之后需要上传的FTP服务器文件路径;QNetworkAccessManager 就是所谓的网络访问管理器,主要靠它来进行文件上传;QNetworkReply 是QNetworkAccessManager 上传时的一个回复对象,可以通过它来得到一些返回的信息
然后,是cpp文件中正式代码部分
//url
QUrl url(uploadUrl);//设置一个ftp路径,例如ftp://xxx/xx/x
url.setPort(ftp_upload_path_info.ftpport);//端口号
url.setUserName(ftp_upload_path_info.ftpaccount);//用户名
url.setPassword(ftp_upload_path_info.ftppws);//密码
//给指针添加实例
accessManager = new QNetworkAccessManager();
accessManager->setNetworkAccessible(QNetworkAccessManager::Accessible);//设置可网络访问
QNetworkRequest request(url);//将QUrl设置进网络请求类QNetworkRequest 中
//该读取文件的方法,在1G以上的文件时会导致直接上传失败
//ftp_file = new QFile(filenamepath);
//ftp_file->open(QIODevice::ReadOnly);
//QByteArray byte_file = ftp_file->readAll();
//解决大文件的上传
QFile *data = new QFile(filenamepath,this);
if(data->open(QIODevice::ReadOnly))
{
}
reply = accessManager->put(request, data/*byte_file*/); //发送上传请求
connect(accessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(loadError(QNetworkReply::NetworkError)));
connect(reply, SIGNAL(uploadProgress(qint64 ,qint64)), this, SLOT(loadProgress(qint64 ,qint64)));
代码不是很多,一步步来看。首先QUrl你要设置路径、端口号、用户名和密码,这是与FTP服务器相关的;然后就是正式的QNetworkAccessManager上传,你需要先把url设置进QNetworkRequest 对象中,再通过参数的形式传入QNetworkAccessManager的put方法中。put其实就是上传的意思,除了QNetworkRequest 参数外,你还需要一个文件指针。
这里有两种方法,网上主流的是先用QFile的readAll()来读取,但对于大文件是没办法readAll()的,所以会直接失败。这里将传入QByteArray 数据,改为直接传入QIODevice类型指针(QFile继承),从而解决大文件上传问题。亲测2G以上没问题,只是说文件越大上传速度肯定越慢嘛。
参考:解决QNetworkAccessManager实现ftp功能后,不能上传大于1G文件的问题
另外一个就是信号槽相关,这里我绑定了三条。第一条是QNetworkAccessManager本身的finished信号,这个不管是上传成功,还是上传失败,网络中断超时什么的都会返回,反正是一个结果,你需要通过QNetworkReply参数的错误参数来区分返回结果。
void xxx::replyFinished(QNetworkReply *)
{
qDebug()<<"reply->error()"<<reply->error();
if (reply->error() == QNetworkReply::NoError) //每个文件上传完成都执行
{
qDebug()<<"上传成功";
ftp_file->close();//文件操作要记得关闭
QMessageBox::about(NULL, "提示", "上传成功!");
}else if((reply->error() == QNetworkReply::OperationCanceledError))
{
//手动取消导致的错误
}
else
{
// QMessageBox::about(NULL, "提示", "上传失败!");
}
}
第二条信号槽也是报错信息,跟第一条类似,但报错时机可能会有区别
void xxx::loadError(QNetworkReply::NetworkError error)
{
qDebug()<<"Transmitted error!!!";
//QMessageBox::about(NULL, "提示", "上传失败!");
}
第三条信号槽就有点意思了,它是上传进度的一个反馈信号,uploadProgress(qint64 ,qint64)的参数分别是当前已上传大小和总大小,例如250,1000这样。
这个信号的触发频率适中,可以用它来做一个进度条的显示。例如用QProgressBar的void setRange(int minimum, int maximum);和void setValue(int value);来设置范围和当前值。
值得一提的是,这里的参数都是int型,而大文件上传的情况下,往往uploadProgress(qint64 ,qint64)的qint64 (long long)是大于int的,如果不自行判断换算一下的话,进度条会没有任何效果和百分比数值哦。
while(bytesTotal > 0x7fffffff)//int的最大值
{
bytesTotal /= 10;
bytesSent /= 10;
}
边栏推荐
- Data storage in memory & loading into memory to make the program run
- Truck History
- 2078. Two houses with different colors and the farthest distance
- Differential (one-dimensional, two-dimensional, three-dimensional) Blue Bridge Cup three body attack
- TCP's three handshakes and four waves
- Shell脚本编程
- 409. Longest palindrome
- 1605. Sum the feasible matrix for a given row and column
- JS call camera
- Opencv learning log 32 edge extraction
猜你喜欢

b站 实时弹幕和历史弹幕 Protobuf 格式解析

Differential (one-dimensional, two-dimensional, three-dimensional) Blue Bridge Cup three body attack

1005. Maximized array sum after K negations

1529. Minimum number of suffix flips

Ball Dropping

1605. Sum the feasible matrix for a given row and column

渗透测试 ( 8 ) --- Burp Suite Pro 官方文档

Borg maze (bfs+ minimum spanning tree) (problem solving report)

Vs2019 initial use

409. Longest palindrome
随机推荐
[exercise-7] crossover answers
Openwrt source code generation image
Sword finger offer II 019 Delete at most one character to get a palindrome
Differential (one-dimensional, two-dimensional, three-dimensional) Blue Bridge Cup three body attack
【练习-3】(Uva 442)Matrix Chain Multiplication(矩阵链乘)
b站 实时弹幕和历史弹幕 Protobuf 格式解析
Socket communication
[exercise-5] (UVA 839) not so mobile (balance)
【练习-1】(Uva 673) Parentheses Balance/平衡的括号 (栈stack)
[exercise-4] (UVA 11988) broken keyboard = = (linked list)
(POJ - 3685) matrix (two sets and two parts)
Determine the Photo Position
栈的经典应用—括号匹配问题
[exercise-1] (UVA 673) parentheses balance/ balanced brackets (stack)
Opencv learning log 31 -- background difference
1689. Ten - the minimum number of binary numbers
X-Forwarded-For详解、如何获取到客户端IP
MySQL授予用户指定内容的操作权限
Hdu-6025-prime sequence (girls' competition)
[exercise-8] (UVA 246) 10-20-30== simulation