libCurl 库sftp上传和下载

来源:互联网 发布:centos 7.3.1611 编辑:程序博客网 时间:2024/05/15 17:42

上传:

size_t DownloadFtp::read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
curl_off_t nread;
/* in real-world cases, this would probably get this data differently
as this fread() stuff is exactly what the library already would do
by default internally */ 
size_t retcode = fread(ptr, size, nmemb, (FILE*)(stream));
nread = (curl_off_t)retcode;
// fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T
// " bytes from file\n", nread);
return retcode;
}



bool DownloadFtp::UpLoad(FILETYPE filetype,const QString& filepath,const QString& filename)
{
FILE* pSendFile = ::fopen(filepath.toStdString().c_str(), "rb");
if(NULL == pSendFile)
{
//fprintf(stderr, "Open file failed at %s:%d\n", __FILE__, __LINE__);
LOGGER_ERROR(m_loggerPtr, "Open file "+filepath+" failed ");
return -1;
}
::fseek(pSendFile, 0L, SEEK_END);
size_t iFileSize = ::ftell(pSendFile);
::fseek(pSendFile, 0L, SEEK_SET);
QString fullpath =""; 
m_pCurlhandle = curl_easy_init();
if (NULL == m_pCurlhandle)
{
LOGGER_ERROR(m_loggerPtr, "Curl handle could not create!");
return false;
}
curl_easy_setopt(m_pCurlhandle, CURLOPT_USERPWD, m_userpwd.c_str());


curl_easy_setopt(m_pCurlhandle, CURLOPT_URL, fullpath.toStdString().c_str());
curl_easy_setopt(m_pCurlhandle, CURLOPT_READDATA, pSendFile);
curl_easy_setopt(m_pCurlhandle, CURLOPT_READFUNCTION, read_callback);
curl_easy_setopt(m_pCurlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, 0);
curl_easy_setopt(m_pCurlhandle, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(m_pCurlhandle, CURLOPT_INFILESIZE, iFileSize);
//qDebug()<<fullpath;
CURLcode r1es = curl_easy_perform(m_pCurlhandle);
if (CURLE_OK!= r1es)
{
LOGGER_ERROR(m_loggerPtr, curl_easy_strerror(r1es));
return false;
}
fclose(pSendFile);
return true;
}

下载:



size_t AchieveModel::my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
struct FtpFile *out=(struct FtpFile *)stream;
if(out && !out->stream) {
/* open file for writing */ 
out->stream=fopen(out->filename.c_str(), "wb");
if(!out->stream)
return -1; /* failure, can't open file to write */ 
}


out->fileSize += size * nmemb;
return fwrite(buffer, size, nmemb, out->stream);
}


size_t AchieveModel::write_response(void *ptr, size_t size, size_t nmemb, void *data)
{
std::string fileList = (char *)ptr;
//qDebug()<<fileList.c_str();
std::string trueFile = fileList;
QString str  = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
QString res = "start download file " + str;
AchieveModel* achieveModel = (AchieveModel*)data;
achieveModel->SetFileInfo(trueFile);
//curl格式要求,应该返回获取的数据大小,才认为函数执行正确; 
return size*nmemb;
}


size_t AchieveModel::length_response(void *ptr, size_t size, size_t nmemb, void *data)
{
std::string fileList = (char *)ptr;
AchieveModel* achieveModel = (AchieveModel*)data;
achieveModel->SetFileInfo(fileList);
//curl格式要求,应该返回获取的数据大小,才认为函数执行正确
return size*nmemb;
}




bool AchieveModel::Init()
{


m_ftpType    = COMTOP::Settings::GetKey("system.ini", "AchieveModel/FtpType");
m_emsCimBaseURL    = COMTOP::Settings::GetKey("system.ini", "AchieveModel/EmsCimPath");
m_emsSvgBaseURL    = COMTOP::Settings::GetKey("system.ini", "AchieveModel/EmsSvgPath");
m_gisCimBaseURL    = COMTOP::Settings::GetKey("system.ini", "AchieveModel/GisCimPath");
m_gisSvgBaseURL    = COMTOP::Settings::GetKey("system.ini", "AchieveModel/GisSvgPath");


QString user      = COMTOP::Settings::GetKey("system.ini", "AchieveModel/User");
QString password  = COMTOP::Settings::GetKey("system.ini", "AchieveModel/Password");
m_rootPath        = COMTOP::Settings::GetKey("system.ini", "RootDirectory/RootPath");
m_emsCimDirection  = COMTOP::Settings::GetKey("system.ini", "AchieveModel/LocalEmsCimDirection");
m_emsSvgDirection  = COMTOP::Settings::GetKey("system.ini", "AchieveModel/LocalEmsSvgDirection");
m_gisCimDirection  = COMTOP::Settings::GetKey("system.ini", "AchieveModel/LocalGisCimDirection");
m_gisSvgDirection  = COMTOP::Settings::GetKey("system.ini", "AchieveModel/LocalGisSvgDirection");
if (m_emsCimBaseURL.isEmpty()||m_emsSvgBaseURL.isEmpty()||user.isEmpty()||password.isEmpty()||m_rootPath.isEmpty()
||m_ftpType.isEmpty()||m_emsCimDirection.isEmpty()||m_emsSvgDirection.isEmpty()
||m_gisCimBaseURL.isEmpty()||m_gisSvgBaseURL.isEmpty()||m_gisCimDirection.isEmpty()||m_gisSvgDirection.isEmpty()
)
{
qDebug()<<"config erro,please check AchieveModel!";
return false;
}
m_userpwd= user+":"+password;
if (m_ftpType.toLower()=="sftp")
{
//sftp://admin@10.10.61.138/
//m_baseURL = "sftp://"+User.toStdString()+"@"+m_baseURL+"/";
m_emsCimBaseURL = "sftp://"+m_emsCimBaseURL+"/";
m_emsSvgBaseURL = "sftp://"+m_emsSvgBaseURL+"/";
m_gisCimBaseURL = "sftp://"+m_gisCimBaseURL+"/";
m_gisSvgBaseURL = "sftp://"+m_gisSvgBaseURL+"/";
}
else if (m_ftpType.toLower()=="ftp")
{
m_emsCimBaseURL = "ftp://"+m_emsCimBaseURL+"//";
m_emsSvgBaseURL = "ftp://"+m_emsSvgBaseURL+"/";
m_gisCimBaseURL = "ftp://"+m_gisCimBaseURL+"//";
m_gisSvgBaseURL = "ftp://"+m_gisSvgBaseURL+"/";
}
else
{
qDebug()<<"not suport other proctol,except ftp\sftp !";
return false;
}
//初始化FTP 获取,Curl模块
m_pCurlhandle = curl_easy_init();
if (NULL == m_pCurlhandle)
{
qDebug()<<"Curl handle could not create!";
return false;
}
curl_easy_setopt(m_pCurlhandle, CURLOPT_USERPWD, m_userpwd.toStdString().c_str());
//sftp 需要单独创建删除对象
if (m_ftpType.toLower()=="sftp")
{
m_pSFTPDeleteFileHandle = curl_easy_duphandle(m_pCurlhandle);
if (NULL == m_pSFTPDeleteFileHandle)
{
qDebug()<<"m_pSFTPDeleteFileHandle handle could not create!";
return false;
}
}
qDebug()<<"AchieveModel init success!";
return true;
}

void AchieveModel::DownloadFile(FILETYPE filetype)
{
QString baseURL = "";
QString localDirection = "";
QString typeFlag = "";
QString fileTypeName;
switch (filetype)
{
case CIM:
baseURL = m_emsCimBaseURL;
localDirection = m_emsCimDirection;
typeFlag = "xml";
fileTypeName = "cim ";
break;
case SVG:
baseURL = m_emsSvgBaseURL;
localDirection = m_emsSvgDirection;
typeFlag = "svg";
fileTypeName = "svg ";
break;
case GISCIM:
baseURL = m_gisCimBaseURL;
localDirection = m_gisCimDirection;
typeFlag = "xml";
fileTypeName = "cim ";
break;
case GISSVG:
baseURL = m_gisSvgBaseURL;
localDirection = m_gisSvgDirection;
typeFlag = "svg";
fileTypeName = "svg ";
break;
default:
break;
}
qDebug()<<"begin down "+fileTypeName;
m_fileInfo = "";
curl_easy_setopt(m_pCurlhandle, CURLOPT_URL, baseURL.toStdString().c_str());
curl_easy_setopt(m_pCurlhandle, CURLOPT_CUSTOMREQUEST, "NLST");
curl_easy_setopt(m_pCurlhandle, CURLOPT_WRITEDATA, this);
curl_easy_setopt(m_pCurlhandle, CURLOPT_WRITEFUNCTION, write_response);
CURLcode r1es = curl_easy_perform(m_pCurlhandle);
// Check for errors 
if(r1es != CURLE_OK)
{
QString errStr = " curl_easy_perform() failed: ";
errStr += curl_easy_strerror(r1es);
qDebug()<<errStr;
}
else
{
//printf("Get file list success! \n");
}


if (m_fileInfo.length() == 0)
{
printf("there are no file to download! \n");
return;
}
//std::vector<std::string> tmpfileList;
std::vector<std::string> fileList;
boost::split(fileList, m_fileInfo, boost::is_any_of("\r\n"));
if (fileList.size() == 0)
{
printf("Download: file list size is empty! \n");
return;
}
for (int i=0; i< fileList.size(); ++i)
{
if (fileList[i].length() == 0)
{
continue;
}
string::size_type idx = fileList[i].find( typeFlag.toStdString());
if ( idx == string::npos )
{
continue;
}
//拆分文件名
if (m_ftpType.toLower()=="sftp")
{
fileList[i] = SplitFileName(QString(fileList[i].c_str()),typeFlag).toStdString();
}
std::string url = baseURL.toStdString() + fileList[i];
CURLcode res;
FtpFile ftpfile;
std::stringstream strStream;
QString strss = fileList[i].c_str();
QString finalfilename;
//拷贝中的文件命临时文件名 *_tmp
finalfilename = strss +"_tmp";
if (m_ftpType.toLower()=="sftp")
{
QString strtmp = QString::fromUtf8(finalfilename.toStdString().c_str());
QByteArray ba = strtmp.toLocal8Bit(); 
finalfilename = ba.data();
}
strStream << localDirection.toStdString() << "/"  << finalfilename.toStdString();
strStream >> ftpfile.filename;
ftpfile.stream = NULL;


curl_easy_setopt(m_pCurlhandle, CURLOPT_URL, url.c_str());
curl_easy_setopt(m_pCurlhandle, CURLOPT_CONNECTTIMEOUT, 60);//cgd - 2015-05-25
curl_easy_setopt(m_pCurlhandle, CURLOPT_WRITEFUNCTION, my_fwrite);
curl_easy_setopt(m_pCurlhandle, CURLOPT_WRITEDATA, &ftpfile);
//使用最低速度超时的方式,避免网络断开导致的线程卡死
curl_easy_setopt(m_pCurlhandle, CURLOPT_LOW_SPEED_LIMIT, 1);
curl_easy_setopt(m_pCurlhandle, CURLOPT_LOW_SPEED_TIME, 60);
res = curl_easy_perform(m_pCurlhandle);


if(ftpfile.stream)
fclose(ftpfile.stream);
QString tmpname = localDirection+"/"+finalfilename;
QString finalname = tmpname.left(tmpname.length()-4);//去掉_tmp
//删除原有文件
QFile::remove(finalname);
QFile::rename(tmpname,finalname);
//CURLE_REMOTE_FILE_NOT_FOUND-是因为试图去下载文件夹;CURLE_PARTIAL_FILE是因为文件未完全
if(CURLE_OK != res && CURLE_REMOTE_FILE_NOT_FOUND != res && CURLE_PARTIAL_FILE != res) 
{
string errStr = " curl told us error type : ";
errStr = curl_easy_strerror(res);
errStr += " - " + url;
qDebug()<<errStr.c_str();
}
else
{
//跳过空文件
if (ftpfile.fileSize == 0)
{
continue;
}
}


//配网文件取完以后删除掉
if(filetype == GISCIM)
{
if (m_ftpType.toLower()=="sftp")
{//sftp 删除文件需要用 rm命令,且路径需要全路径
struct curl_slist *headerlist=NULL;


std::string tmp = baseURL.toStdString().substr( strlen("sftp://") );
int npos = tmp.find("/");
std::string strPath = tmp.substr(npos);
std::string rmFileCmd = "rm " + strPath + fileList[i];


headerlist = curl_slist_append( headerlist, rmFileCmd.c_str() );
curl_easy_setopt(m_pSFTPDeleteFileHandle, CURLOPT_URL, baseURL.toStdString().c_str());
curl_easy_setopt(m_pSFTPDeleteFileHandle, CURLOPT_POSTQUOTE, headerlist);
CURLcode resDel = curl_easy_perform(m_pSFTPDeleteFileHandle); //发送DELETE请求
std::string strErrMsg = curl_easy_strerror(resDel);
curl_slist_free_all (headerlist);
if (resDel != CURLE_OK)
{
qDebug()<< strErrMsg.c_str();
}
}
else
{//ftp没sftp那么麻烦
std::string del = "DELE " + fileList[i];
curl_easy_setopt(m_pCurlhandle, CURLOPT_URL, baseURL.toStdString().c_str() );//
curl_easy_setopt(m_pCurlhandle, CURLOPT_CUSTOMREQUEST, del.c_str() );
CURLcode resDel = curl_easy_perform(m_pCurlhandle); //发送DELETE请求
std::string strErrMsg = curl_easy_strerror(resDel);
if (resDel != CURLE_OK)
{
qDebug()<<  strErrMsg.c_str();
}
}
}
}
string errStr = "download file " + fileTypeName.toStdString() + " success  ";
qDebug()<<errStr.c_str();
m_fileInfo.clear();
}


0 0
原创粉丝点击