前言
基于QT来实现FTP并不是什么难事,有以下三种解决方案:
Android/PC代码一致
1.使用网络管理模块(实现上传下载);
mMgr =new QNetworkAccessManager();
mUrl = new QUrl();
mUrl->setScheme("ftp");
mUrl->setHost(ip);
mUrl->setPort(port);
void JHFtp::get(QString src, QString des){
QFileInfo info;
info.setFile(des);
mFile = new QFile(info.filePath());
if(mFile->open(QIODevice::WriteOnly)){
qDebug()<<"file opened";
mUrl->setPath(src);
}
mReply = mMgr->get(QNetworkRequest(*mUrl));
connect(mReply,SIGNAL(readyRead()),this,SLOT(readData()));
connect(mReply,SIGNAL(finished()),this,SLOT(finishGet()));
connect(mReply,SIGNAL(finished()),mReply,SLOT(deleteLater()));
connect(mReply,static_cast<void(QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),this,[&](QNetworkReply::NetworkError){
if(mReply)
qDebug()<<mReply->errorString();
});
connect(mReply, SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(error(QNetworkReply::NetworkError)));
connect(mReply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(progressUpdated(qint64,qint64)));
}
QFile file(src);
QByteArray data;
if(file.open(QIODevice::ReadOnly)){
data = file.readAll();
}
file.close();
mUrl->setPath(des);
mReply=mMgr->put(QNetworkRequest(*mUrl), data);
connect(mReply,SIGNAL(finished()),this,SLOT(finishPut()));
connect(mReply, SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(error(QNetworkReply::NetworkError)));
connect(mReply,SIGNAL(finished()),mReply,SLOT(deleteLater()));
connect(mReply,SIGNAL(uploadProgress(qint64,qint64)),this,SLOT(progressUpdated(qint64,qint64)));
2.使用curl 网络类库;
get/put实现比较简单就不写了主要写一下实现列表获取以及中文处理:
CURL *curl=curl_easy_init();
CURLcode res;
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_URL, "ftp://188.***.***.***/");
curl_easy_setopt(curl, CURLOPT_USERPWD, "user***:pass****");
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, ftpwrite);
curl_easy_setopt(curl,CURLOPT_DNS_CACHE_TIMEOUT,50);
res = curl_easy_perform(curl);
if(res != CURLE_OK){
return -1;
}
qDebug()<<"OK";
curl_easy_cleanup(curl);
return 1;
很多人采用这种方式:得到中文乱码:
static size_t callback(void *ptr, size_t size, size_t nmemb, void *stream) {
QString msg;
msg =QString((char *) ptr);
rec_data += msg;
rn size * nmemb;
}
由于编码不一致导致,建议采用:
static size_t ftpwrite(void *ptr, size_t size, size_t nmemb, void *data)
{
QString msg;
msg =QString::fromLocal8Bit((char *)ptr);
qDebug()<<"MSG:"<<msg;
ftp += msg;
return size * nmemb;
}
3.使用QFtp
ftp2 = new QFtp(o);
ftp2->connectToHost("218.***.***.***", ***);
ftp2->login("user*****","pass****");
connect(ftp2,SIGNAL(listInfo(QUrlInfo)),this,SLOT(listInfo(QUrlInfo)));
connect(ftp2,SIGNAL(dataTransferProgress(qint64,qint64)),this,SLOT(progressSlot(qint64,qint64)));
////获取列表
ftp2->list();
////创建yjhlog
ftp2->mkdir("yjhlog");
///重命名
ftp2->rename(z,b);
/// 删除
ftp2->remove(fname);
///下载
ftp2->get(path+"/"+name,pFile);
////上传
ftp2->put(arry,spath);
在QFtp 基础上进行了封装:附带model 以及状态:
ftp2 = new QtFtp(o);
ftp2->setFtp("***.***.***.***", port,"user","pass");
connect(ftp2,&QtFtp::updateModel,this,[=](bool clear){
qDebug()<<clear;
pEngine->rootContext()->setContextProperty("fmodel",QVariant::fromValue(ftp2->filesModel));
if(clear){
ftp2->clearModel();
}
});
pEngine->rootContext()->setContextProperty("fmodel",QVariant::fromValue(ftp2->filesModel));
ftp2->connectFtp();
ftp2->load();
void MainApp::backDir(){
ftp2->back();
}
void MainApp::downloadF(QString name){
ftp2->downFile(name,QDir::currentPath());
}
void MainApp::upFile(QString name){
name="D:/WinStartLog.log";
ftp2->upFile(name);
}
void MainApp::rename(QString olds,QString news){
ftp2->reName(olds,news);
}
void MainApp::deleteFile(QString fname){
ftp2->deleteFile(fname);
}
void MainApp::updateModel(QString s){
ftp2->load(s);
截图
PC:
Android:
界面什么的 目前没时间整 随便写了一下 先用着,后期整理一下PC Android同步发布。