curl -- Qt中使用FTP传递文件

源码:https://curl.haxx.se/

http://blog.csdn.net/vipfengxiao/article/details/6027742 
https://blog.csdn.net/zengraoli/article/details/11517367
https://curl.haxx.se/download/?C=M;O=D 

源码下载下来后,--VS2013的编译源码方法:

编译 libcurl  步骤:打开 F:\curl-7.61.0\curl-7.61.0\winbuild\BUILD.WINDOWS.txt,依照里面的说明,打开VS2013的命令提示符,进入 F:\curl-7.61.0\curl-7.61.0\winbuild路径,然后执行 nmake /f Makefile.vc mode=dll VC=12 ENABLE_IDN=no DEBUG=no MACHINE=x64  ,然后生成 libcurl.dll libcurl.lib。

进入到 curl.exe 同级目录下面,在此目录下面的命令行中,可以执行curl命令,参见 https://blog.csdn.net/yxys01/article/details/77190619?locationNum=3&fps=1 

curl的使用示例: https://curl.haxx.se/libcurl/c/example.html

下面是一些部分代码:

struct  stFileInfor{
	string strFileName;
	int	   iFileSize;
	string strModify;
	string strFileType;//是文件夹还是文件
	stFileInfor(){
		strFileName = "";
		iFileSize = 0;
		strModify = "";
		strFileType = "";
	}
};

static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
	curl_off_t nread;
	size_t retcode = fread(ptr, size, nmemb, (FILE*)stream);
	nread = (curl_off_t)retcode;
	return retcode;
}

size_t WritedData(void *buffer, size_t size, size_t nmemb, void *userp){
	int segsize = size * nmemb;
	string * pstr = (string*)userp;
	char* cTemp = (char *)malloc((segsize + 1)*sizeof(char));
	memset(cTemp, 0, sizeof(char) * segsize + 1);
	memcpy((void *)cTemp, buffer, (size_t)segsize);
	(*pstr) += ((string)cTemp);
	free(cTemp);
	return segsize;
}

size_t DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam)
{
	FILE* fp = (FILE*)pParam;
	size_t nWrite = fwrite(pBuffer, nSize, nMemByte, fp);
	return nWrite;
}

void split(string* sec, string delim, vector<string>* ret)
{
	if (NULL == sec || NULL == ret)
		return;

	size_t last = 0;
	size_t index = (*sec).find_first_of(delim, last);
	while (index != string::npos){
		string strSub = (*sec).substr(last, index - last);
		if ("" != strSub){
			ret->push_back(strSub);
		}
		last = index + 1;
		index = (*sec).find_first_of(delim, last);
	}
	if (index - last > 0){
		string strSub = (*sec).substr(last, index - last);
		if ("" != strSub){
			ret->push_back(strSub);
		}
	}
}

string split_getlast(std::string s, std::string delim)
{
	vector<string> vecPath;
	split(&s, delim, &vecPath);
	for (int iIndex = (vecPath.size() - 1); iIndex >= 0; iIndex--){
		if ("" != vecPath[iIndex])
			return vecPath[iIndex];
	}
	return "";
}

string connectPath(string strPath, string strConPath)
{
	string strRePath = "";
	boost::filesystem::path Path = strPath;
	strRePath = (Path / strConPath).string();
	return strRePath;
}

void ParsFileInfor(string* strFileData, vector<stFileInfor>* ret)
{
	vector<string> vecFileList;
	split(strFileData, "\n", &vecFileList);
	for (int iIndex = 0; iIndex < vecFileList.size(); iIndex++){

		stFileInfor st;
		vector<string> vecFileInfo;
		split((&vecFileList[iIndex]), ";", &vecFileInfo);

		for (int i = 0; i < vecFileInfo.size(); i++){
			size_t index = string::npos;
			//index != string::npos;
			if ((index = vecFileInfo[i].find("Type")) != string::npos){
				st.strFileType = vecFileInfo[i].substr(index + 5);
			}
			else if ((index = vecFileInfo[i].find("Size")) != string::npos){
				st.iFileSize = atoi(vecFileInfo[i].substr(index + 5).c_str());
			}
			else if ((index = vecFileInfo[i].find("Modify")) != string::npos){
				st.strModify = vecFileInfo[i].substr(index + 7);
			}
			else{
				st.strFileName = vecFileInfo[i];
				st.strFileName.erase(0, st.strFileName.find_first_not_of(" "));
				st.strFileName.erase(st.strFileName.find_last_not_of(" ") + 1);
				st.strFileName.erase(st.strFileName.find_last_not_of("\n") + 1);
				st.strFileName.erase(st.strFileName.find_last_not_of("\r") + 1);
			}
		}
		if ("." != st.strFileName){
			ret->push_back(st);
		}

	}
}

string  GetFilePath(string strPath)
{
	bool bGet = false;
	string strFilePath = "";
	if (!boost::filesystem::exists(strPath)){
		//bool bcreat = boost::filesystem::create_directories(strPath);
		bool bcreat = boost::filesystem::create_directory(strPath);
		if (bcreat)//不存在则创建目录
		{
			strFilePath = strPath;
		}
		else
			strFilePath = "";
	}
	else{
		strFilePath = strPath;
	}
	return strFilePath;
}

bool GetFtpFileList(char* cpAccount, char* cpPassWord, char* cpFilePath, vector<stFileInfor>* vecFileInfor, string& strError){
	try{
		CURL *curl;
		CURLcode res;
		curl = curl_easy_init();
		string strReFileList = "";
		if (curl) {
			/* Get a file listing from sunet */
			curl_easy_setopt(curl, CURLOPT_USERNAME, cpAccount);
			curl_easy_setopt(curl, CURLOPT_PASSWORD, cpPassWord);
			curl_easy_setopt(curl, CURLOPT_URL, cpFilePath);
			curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "MLSD");// MLSD\r
			curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WritedData);
			curl_easy_setopt(curl, CURLOPT_WRITEDATA, ((void*)&strReFileList));
			res = curl_easy_perform(curl);
			/* Check for errors */
			if (res != CURLE_OK)
				fprintf(stderr, "curl_easy_perform() failed: %s\n",
				curl_easy_strerror(res));
			/* always cleanup */
			curl_easy_cleanup(curl);
		}
		ParsFileInfor(&strReFileList, vecFileInfor);
		return true;
	}
	catch (exception &e){
		strError = "Exception Occurs :" + string(e.what());
		return false;
	}
}

bool DownloadFtpFile(char* cpAccount, char* cpPassWord, char* cpUrlDownloadAddress, char* cpPath, string& strError)
{
	try{
		bool bResult = false;
		//初始化curl,这个是必须的  
		CURL *curl = curl_easy_init();
		curl_easy_setopt(curl, CURLOPT_URL, cpUrlDownloadAddress);
		string strFileName = cpPath;
		if ("" == strFileName){
			strFileName = split_getlast(cpUrlDownloadAddress, "\/");
			if ("" == strFileName){
				strFileName = split_getlast(cpUrlDownloadAddress, "\\");
			}
		}
		//设置接收数据的回调 
		FILE* file = fopen(const_cast<char*>(strFileName.c_str()), "wb");
		if (NULL == curl || NULL == file){
			strError = "fileopen erro: " + string(cpPath);
			return false;
		}
		curl_easy_setopt(curl, CURLOPT_USERNAME, cpAccount);
		curl_easy_setopt(curl, CURLOPT_PASSWORD, cpPassWord);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DownloadCallback);
		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
		curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5);
		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
		curl_easy_setopt(curl, CURLOPT_NOPROGRESS, true);
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
		CURLcode retcCode = curl_easy_perform(curl);
		fclose(file);

		if (retcCode != CURLE_OK){
			strError = "download failure URL=  " + string(cpUrlDownloadAddress) + ";reason = " + curl_easy_strerror(retcCode);
		}
		else{
			long responseCode = 0;
			curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
			struct _stat info;
			_stat(cpPath, &info);
			//int size = info.st_size;

			if ((200 <= responseCode) &&
				responseCode < 300){
				bResult = true;
			}
			else if (responseCode < 200 || responseCode >= 300){
				strError = "download failure URL=  " + string(cpUrlDownloadAddress) + ";reason = " + curl_easy_strerror(retcCode);
				bResult = false;
			}
		}
		//清理curl,和前面的初始化匹配  
		curl_easy_cleanup(curl);
		return bResult;
	}
	catch (exception &e){
		strError = "Exception Occurs :" + string(e.what());
		return false;
	}
}

bool DownloadFtpFolder(char* cpAccount, char* cpPassWord, char* cpUrlDownloadAddress, char* cpPath, string& strError){

	try{
		string strFoldName = split_getlast(cpUrlDownloadAddress, "\/");
		if ("" == strFoldName){
			strFoldName = split_getlast(cpUrlDownloadAddress, "\\");
		}
		string strTarFile = connectPath(cpPath, strFoldName);
		strTarFile = GetFilePath(strTarFile);

		vector<stFileInfor> vecFileList;
		GetFtpFileList(cpAccount, cpPassWord, cpUrlDownloadAddress, &vecFileList, strError);

		for (int i = 0; i < vecFileList.size(); i++){
			if (vecFileList[i].strFileType == "dir"){
				string strUrlDownloadAddress = cpUrlDownloadAddress;
				strUrlDownloadAddress = strUrlDownloadAddress + vecFileList[i].strFileName + "\/";
				DownloadFtpFolder(cpAccount, cpPassWord, const_cast<char*>(strUrlDownloadAddress.c_str()), const_cast<char*>(strTarFile.c_str()), strError);
			}
			else if (vecFileList[i].strFileType == "file"){
				string strUrlDownloadAddress = cpUrlDownloadAddress;
				strUrlDownloadAddress += vecFileList[i].strFileName;
				string strTarFileTemp = connectPath(strTarFile, vecFileList[i].strFileName);
				DownloadFtpFile(cpAccount, cpPassWord, const_cast<char*>(strUrlDownloadAddress.c_str()), const_cast<char*>(strTarFileTemp.c_str()), strError);
			}
		}
		return true;
	}
	catch (exception &e){
		strError = "Exception Occurs :" + string(e.what());
		return false;
	}
}

bool UpFtpFile(char* cpAccount, char* cpPassWord, char* cpUrl, char* cpPath, string& strError)
{
	try
	{
		CURL *curl;
		CURLcode res;
		FILE *hd_src;
		struct stat file_info;
		curl_off_t fsize;

		struct curl_slist *headerlist = NULL;
		if (stat(cpPath, &file_info)) {
			strError = string(cpPath) + " open erro ;reason = " + strerror(errno);
			return false;
		}
		fsize = (curl_off_t)file_info.st_size;
		/* get a FILE * of the same file */
		hd_src = fopen(cpPath, "rb");
		/* In windows, this will init the winsock stuff */
		curl_global_init(CURL_GLOBAL_ALL);
		/* get a curl handle */
		curl = curl_easy_init();
		if (curl) {
			/* we want to use our own read function */
			curl_easy_setopt(curl, CURLOPT_USERNAME, cpAccount);
			curl_easy_setopt(curl, CURLOPT_PASSWORD, cpPassWord);
			curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
			curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
			curl_easy_setopt(curl, CURLOPT_URL, cpUrl);
			curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
			curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize);
			res = curl_easy_perform(curl);
			if (res != CURLE_OK){
				strError = "up failure; filename = " + string(cpPath) + "; URL = " + string(cpUrl) + "; reason = " + curl_easy_strerror(res);
			}
			/* always cleanup */
			curl_easy_cleanup(curl);
		}
		fclose(hd_src); /* close the local file */
		curl_global_cleanup();
		return (res == CURLE_OK);
	}
	catch (exception &e){
		strError = "Exception Occurs :" + string(e.what());
		return false;
	}
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值