1. 程式人生 > >libCurl 庫sftp上傳和下載

libCurl 庫sftp上傳和下載

上傳:

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://[email protected]/
//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();
}

相關推薦

libCurl sftp下載

上傳: size_t DownloadFtp::read_callback(void *ptr, size_t size, size_t nmemb, void *stream) {curl_off_t nread;/* in real-world cases, this

SFTP下載服務器文件

一個 span nbsp linux 文件 遠程 ftp上傳 主機 連接 sftp 是一個交互式文件傳輸程式。它類似於 ftp, 但它進行加密傳輸,比FTP有更高的安全性。 連接服務器 sftp [email protected] 或者 [email protected]

SFTP下載檔案指令碼

運維工作中,遠端上傳或下載檔案很常用,我分享下我經常使用的sftp指令碼 #!/bin/bash SCRIPT_NAME=`basename $0` CURRENT_DIR=$(cd "$(dirna

JAVA實現SFTP檔案下載(利用JSCH.jar)

原文連結:https://my.oschina.net/hetiangui/blog/137357如果你想用純JAVA實現SFTP檔案上傳或下載,或者是想純JAVA連線到SSH2伺服器上執行命令,那就使用JSch.jar包吧。這裡我們先描述實現SFTP協議的上傳和下載,上程式

java sftp 的檔案下載

package com.taikang.ftp;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;impo

Linux - 通過SecureCRT的rz、szsftp實現文件的下載

received 文件的 get 基礎 數據 aid 操作 art 強制 目錄 1 通過rz/sz命令上傳/下載 1.1 安裝lrzsz軟件 1.2 rz - 上傳文件 1

Java中的文件下載

獲取 https res 文件內容 tty type() val name 表單 文件上傳原理:   早期的文件上傳機制:     在TCP/IP中。最早出現的文件上傳機制是FTP。他是將文件由客戶端發送到服務器的標準機制。   jsp中的文件上傳機制:     在jsp編

文件下載

分析 bst 通過 zemax get char 避免 獲取文件 list 一、文件的上傳和下載   1、文件上傳的原理分析     1.1文件上傳的必要前提:       a、提供form表單,method必須是post       b、form表單的encty

步步為營-70-asp.net簡單練習(文件的下載)

public post local 程序 上傳 summary 提交 created lns 大文件的上傳一般通過FTP協議,而一般小的文件可以通過http協議來完成 1 通過asp.net 完成圖片的上傳 1.1 創建html頁面   註意:1 method="post"

IOS http(下載)

fig pla nil style span atof port use userinfo HttpTool.h #import <Foundation/Foundation.h> typedef void (^HttpToolProgressBlock

linux下使用rzsz實現文件的下載

輸入 ssh登錄 usr 終端 啟動 mode 裝包 ftw soft 新搞的雲服務器用SecureCRT不支持上傳和下載,沒有找到rz命令。記錄一下如何安裝rz/sz命令的方法。 一、工具說明 在SecureCRT這樣的ssh登錄軟件裏, 通過在L

windows、linux通過ftp從ftp服務器下載

關閉 註意 head ros 實現 des blog family pro 最近需要用到文件的上傳和下載,查看我們使用的系統,發現有一個進程為t_ftpd,懷疑其為一個ftp的守護進程,於是想要用ftp的方式實現。 在windows上使用bat腳本的方式實現: 首先寫一個b

struts2學習(13)struts2文件下載(1)

action alt for ide 上傳文件 fig .org dac str 一、Struts2文件上傳: 二、配置文件的大小以及允許上傳的文件類型: 三、大文件上傳: 如果不配置上傳文件的大小,struts2默認允許上傳文件最大為2M; 2097152Byte;

struts2學習(14)struts2文件下載(4)多個文件下載

sym ring spl out urn ide http iso length 四、多個文件上傳: 五、struts2文件下載: 多個文件上傳action com.cy.action.FilesUploadAction.java: package com.cy.a

Java實現FTP文件與文件夾的下載

連接 rem odi 一個 nec stat mod plog erlang Java實現FTP文件與文件夾的上傳和下載   FTP 是File Transfer Protocol(文件傳輸協議)的英文簡稱,而中文簡稱為“文傳協議”。用於Int

Linux命令:scp命令(文件下載)

roo dir lin 10.10 文件上傳和下載 cp命令 scp inux scp命令 Linux命令:scp命令(文件上傳和下載) #本地下載遠端文件 並且重命名(從本地機器下載遠端)scp [email protected]/* */:/ROOT/lo

Java下載

false 文件下載 解碼 取字符串 前綴 3.1 esp lena val 1.文件的上傳   [1] 簡介     > 將一個客戶端的本地的文件發送到服務器中保存。     > 上傳文件是通過流的形式將文件發送給服務器。   [2]

文件或資源的下載

輸入 lastindex out ext str left mime 所在 tty 1.文件的上傳 [1] 簡介 > 將一個客戶端的本地的文件發送到服務器中保存。 > 上傳文件是通過流的形式將文件發送給服務器。 [2] 表單的設置 > 向服務器上傳一個

nexus搭建maven私服及私服jar包下載

ive 校驗 public 我們 賬號 依賴 detail 接下來 triangle nexus搭建maven私服及私服jar包上傳和下載 標簽: nexus管理maven庫snapshot 2017-06-28 13:02 844人閱讀 評論(0) 收

python之FTP下載

塊大小 對象 direct 實例 color 二進制文件 pass nbsp orb 1 # FTP操作 2 import ftplib 3 4 host = ‘192.168.20.191‘ 5 username = ‘ftpuser‘ 6 passwor