VC实现上传文件到FTP服务器

41 篇文章 1 订阅

CurlFTP.h

#pragma once

#include <curl/curl.h>
#include <string>
/*
功能:上传文件到FTP服务器,支持进度条,支持上传操作完成后通知调用者线程。
限制:[1]当前进程只能有一个CCurlFTP实例
      [2]只支持逐个文件上传
作者:kagula
时间:2010-08-19
最后修改时间:2012-10
修改次数:4
修改日志:[1-1]修正makeFullName函数不能正确处理含“\\”字符文件路径的问题。
          [1-2]添加断点上传功能。
		  [2-1]为方便应用层以同步方式使用,做了些必要修改。
		  [2-2]对代码进行改进。
		  [3-1]添加删除文件夹功能。
          [4-1]添加测试FTP连接功能
环境:VS2008SP1 + libcurl 7.21.1 + boost 1.43
备注:可以从下面的URL下载libcurl,并编译成DLL(Release)形式!
      http://curl.haxx.se/libcurl/
	  《libcurl教程》
	  http://blog.csdn.net/JGood/archive/2009/11/08/4787670.aspx
索引关键词:VC实现上传文件到Windows FTP服务器
*/

#define  _CF_BUF_SIZE_   256

//下面是回调Class
class IUploadEvent
{
public:
	//回调函数只是完成变量之间赋值,必须马上返回控制权给CCurlFTP实例所在的线程

	//通知当前进度,取值范围0~1
	virtual void setProgress(float fV)=0;
	//通知上传操作完成,true成功,false失败!
	virtual void done(bool bSuccess)=0;
};

//CCurlFTP_FILE_INFO这个结构体用来存放文件在服务器中的信息
struct CCurlFTP_FILE_INFO{
	std::string  urlFileName;
	time_t       filetime;
	double       filesize;
};

//下面是实现上传功能的Class
class CCurlFTP
{
public:
	CCurlFTP(void);
	~CCurlFTP(void);

	/********************************以下为外部接口*************************************/

	//设置FTP服务器地址
	//入口参数:ip: URL地址
    //          usrpwd:用户名:密码       注意:中间用“:”符号分隔
	//接口使用示例:ip=L"ftp://192.168.0.211";  usrpwd=L"lijun:123456";
	//
	//同时[1]测试服务器是否可以连接[2]如果可以连接,是否支持断点续传?
	//运行结果可以通过调用isSupportREST()方法和isAbilityConn()方法得到。
	void setServeAddr(const wchar_t *ip,const wchar_t *usrpwd);

	//上传文件名为filename的文件到FTP服务器。注意,这是个同步函数!
	//参数说明:源文件名(可以是绝对路径),上传后文件名
	//接口使用示例:filename=L"待上传测试文件.rar";uploadFilename=NULL;不更改文件名
	bool uploadFile(wchar_t *filename,wchar_t *uploadFilename);

	//设置回调实例
	void setCaller(IUploadEvent *call)
	{
		m_call = call;
	}

	//取消当前上传任务
	void abort();

	//当前上传任务是否在运行
	bool isRun()	{ return m_bRun; }
	//删除指定的文件,删除成功返回true
	bool deleteFile(std::wstring filename);
	bool deleteFile(std::string fileName);
	//删除指定的文件夹,删除成功返回true
	bool deleteFolder(std::wstring foldername);
	bool deleteFolder(std::string foldername);
    //新建指定的文件夹,成功返回true
	bool createFolder(std::wstring foldername);
	bool createFolder(std::string  foldername);
	//文件服务器是否支持断点续传
	bool isSupportREST();
	//读取文件在文件服务器的信息
	bool getRemoteFileInfo(std::string sRemoteFileName,CCurlFTP_FILE_INFO &FileInfo);
	//测试FTP服务器是否可以连接
	int  isAbilityConn();

	/********************************以下为内部接口*************************************/
	//读取文件中的数据。回调函数
	static size_t readFromDisk(char *bufptr, size_t size, size_t nitems, void *userp);
	char *      w2c(const wchar_t *pwstr,char *pcstr, size_t len);
	long long   getFileSize() { return  m_filesize; }
	float       getProgress() { return m_fProgress; }
	int         getStatus()   { return m_nStatus; }
	int         getIsAbilityConn()   { return m_isAbilityConn; }
	void        setAbilityConn(int n) { m_isAbilityConn = n; } 

protected:
private:
	static	curl_off_t m_filesize;
	//上传操作状态
	/*
	m_nStatus:执行文件上传的状态
			-1,没有上传任务 或 上传文件失败
			 0,上传文件成功
			 1,正在上传文件
    */
	static int        m_nStatus;
	//用户是否终止
	static bool       m_bAbort;
	//当前是否在执行上传操作,若是m_bRun=true,elsewise the variable m_bRun is false!
	static	bool       m_bRun;
	//最后一次执行上传的远程文件信息
	struct CCurlFTP_FILE_INFO m_fi;
	static float       m_fProgress;
	//
	static bool        m_isREST;
    //是否可连接
	/*
	21:可连接
	67:密码错误
	7: 无法连接,可能IP
	*/
	static int         m_isAbilityConn;

    CURL *     m_easyhandle;
	char       m_ip[_CF_BUF_SIZE_];
	char       m_usrpwd[_CF_BUF_SIZE_];
	char       m_errbuf[_CF_BUF_SIZE_];
	wchar_t    m_filename[_CF_BUF_SIZE_];
	static     IUploadEvent *m_call;

	bool        isFileExist(wchar_t * filename);
	bool        isFileRead(wchar_t * filename);
	char *      makeFullName(char *ip,wchar_t * filename,wchar_t * uploadfilename);
};


 

CurlFTP.cpp

#include "StdAfx.h"
#include "CurlFTP.h"

#include <io.h>
#include <stdlib.h>
#include <boost/thread/mutex.hpp>
#include <boost/thread/locks.hpp>

#include "MyUtility.h"

#pragma comment(lib,"libcurl_imp.lib")
//并把libcurl.dll文件放到当前程序的运行路径中

boost::mutex g_ftp;

IUploadEvent *CCurlFTP::m_call = NULL;
curl_off_t    CCurlFTP::m_filesize = 0;
float         CCurlFTP::m_fProgress = 0;
int           CCurlFTP::m_nStatus = -1;//没有上传任务
bool          CCurlFTP::m_bRun = false;//当前没有任务运行
bool          CCurlFTP::m_bAbort = false;
bool          CCurlFTP::m_isREST = false;
int           CCurlFTP::m_isAbilityConn = 1;//=1状态未知,=0成功

static size_t throw_away(void *ptr, size_t size, size_t nmemb, void *data)
{
  (void)ptr;
  (void)data;
  /* we are not interested in the headers itself,
     so we only return the size we would have saved ... */ 
  return (size_t)(size * nmemb);
}

CCurlFTP::CCurlFTP(void)
{
	memset(m_ip,0,sizeof(m_ip));
	memset(m_usrpwd,0,sizeof(m_usrpwd));

	curl_global_init(CURL_GLOBAL_DEFAULT);
}

CCurlFTP::~CCurlFTP(void)
{		
	curl_global_cleanup();
}

void CCurlFTP::setServeAddr(const wchar_t *ip,const wchar_t *usrpwd)
{
	boost::lock_guard<boost::mutex> l(g_ftp);

	w2c(ip,m_ip,wcslen(ip)*2+1);
	w2c(usrpwd,m_usrpwd,wcslen(usrpwd)*2+1);

	if( 0 == isAbilityConn() )
	{
		m_isREST = isSupportREST();
	}
}

//return the number of bytes it wrote in the buffer. Returning 0 will signal the end of the upload
size_t CCurlFTP::readFromDisk(char *bufptr, size_t size, size_t nitems, void *userp)
{
	boost::lock_guard<boost::mutex> l(g_ftp);
#define  fp   ((FILE*)userp)
	static int nRead;

	if (fp==NULL)
	{
		OutputDebugStringA("size_t CCurlFTP::readFromDisk fp==NULL return 0;");
		return 0;
	}

	if (CCurlFTP::m_bRun==false)
	{
		OutputDebugStringA("size_t CCurlFTP::readFromDisk CCurlFTP::m_bRun==false return 0;");
		return 0;
	}

	if (feof(fp))
	{
		OutputDebugStringA("size_t CCurlFTP::readFromDisk feof(fp) return 0;");
		return 0;
	}

	if (CCurlFTP::m_bAbort)
	{
		OutputDebugStringA("size_t CCurlFTP::readFromDisk CCurlFTP::m_bAbort return 0;");
		return 0;
	}

	//显示当前文件位置
	int nPos;
	nPos = ftell(fp);
	m_fProgress = nPos/( (float)CCurlFTP::m_filesize );
	if (CCurlFTP::m_call)
	{
		m_call->setProgress( m_fProgress );
	}

	//从磁盘中读数据,通常size=1,nitems=16*1024
	nRead = fread(bufptr,size,nitems,fp);
	if (nRead >0)
		return nRead;
	return 0;
}

bool CCurlFTP::uploadFile(wchar_t *bufFileName,wchar_t *uploadFilename)
{
	//待上传文件是否存在
	if (!isFileExist(bufFileName))
	{
		OutputDebugString(L"[CCurlFTP::uploadFile]文件不存在\n");
		return false;
	}

	//待上传文件是否可读
	if (!isFileRead(bufFileName))
	{
		OutputDebugString(L"[CCurlFTP::uploadFile]文件无法读取\n");
		return false;
	}

	//检查是否已经有任务在运行
	if (m_bRun)
	{
		OutputDebugString(L"[CCurlFTP::uploadFile]不允许同时上传多个文件!\n");
		return false;
	}
	{
		boost::lock_guard<boost::mutex> l(g_ftp);
		m_bRun = true;
		m_bAbort = false;
	}

	//查看路徑里面是不是有文件夾名稱,若是
	//為用戶新建文件夾(不管文件夾是否存在)
	std::wstring wsFN = uploadFilename;
	std::string path = ws2s(wsFN);
	std::string folder = getFolderName(path);
	createFolder(folder);

	//取待上传文件,文件大小
	OutputDebugString(L"[CCurlFTP::uploadFile]取待上传文件,文件大小!\n");
	FILE *file=_wfopen(bufFileName,L"rb");
	fseek(file,0,SEEK_END);
	m_filesize = ftell(file);
	fseek(file,0,SEEK_SET);
	memset(m_filename,0,sizeof(m_filename));
	wcsncpy(m_filename,bufFileName,sizeof(m_filename)/sizeof(wchar_t));

	//判断FTP服务器是否支持断点续传
	OutputDebugString(L"[CCurlFTP::uploadFile]判断FTP服务器是否支持断点续传!\n");
	bool isREST = m_isREST;
	if(!isREST)
		OutputDebugString(L"[CCurlFTP::uploadFile]  警告! FTP服务器不支持断点续传!\n");

	//取要上传的文件在服务器中的信息
	OutputDebugString(L"[CCurlFTP::uploadFile]取要上传的文件在服务器中的信息!\n");
	char * pURL = makeFullName(m_ip,bufFileName,uploadFilename);
	OutputDebugStringA("m_ip=");OutputDebugStringA(m_ip);OutputDebugStringA("\n");
	OutputDebugStringW(L"bufFileName=");OutputDebugStringW(bufFileName);OutputDebugStringA("\n");
	OutputDebugStringW(L"uploadFilename=");OutputDebugStringW(uploadFilename);OutputDebugStringA("\n");
	OutputDebugStringA("pURL=");OutputDebugStringA(pURL);OutputDebugStringA("\n");

	bool isFileInfo = getRemoteFileInfo(std::string(pURL),m_fi);
	if(isFileInfo)
	{
		OutputDebugString(L"[CCurlFTP::uploadFile]  FTP服务器已经存在同名文件!\n");
	}

	//准备上传
	OutputDebugString(L"[CCurlFTP::uploadFile]准备上传!\n");
	m_fProgress = .0f;
	long long oldRemoteFileSize=0;
	CURLcode code;
	m_easyhandle = curl_easy_init();
	curl_easy_setopt(m_easyhandle, CURLOPT_URL, pURL); 
	curl_easy_setopt(m_easyhandle, CURLOPT_READFUNCTION, CCurlFTP::readFromDisk); 
	curl_easy_setopt(m_easyhandle, CURLOPT_READDATA    , file); //文件指针传给readFromDisk!
	curl_easy_setopt(m_easyhandle, CURLOPT_UPLOAD      , 1L); 
	curl_easy_setopt(m_easyhandle, CURLOPT_INFILESIZE_LARGE, m_filesize);
	curl_easy_setopt(m_easyhandle, CURLOPT_USERPWD    , m_usrpwd);
	curl_easy_setopt(m_easyhandle, CURLOPT_ERRORBUFFER, m_errbuf);
	curl_easy_setopt(m_easyhandle, CURLOPT_FTPPORT, "-"); /* disable passive mode */
	curl_easy_setopt(m_easyhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);
	curl_easy_setopt(m_easyhandle, CURLOPT_VERBOSE, 1L);
	//如果(支持断点续传 &&
	//要上传的文件已经存在于服务器中 &&
	//要上传的文件上次只上传了一部份)
	if(isREST && isFileInfo && m_fi.filesize<m_filesize)
	{
		//进行断点续传	
		OutputDebugStringA("进行断点续传\n");
		fseek(file,m_fi.filesize,SEEK_SET);
		oldRemoteFileSize = m_fi.filesize;

		curl_easy_setopt(m_easyhandle, CURLOPT_NOBODY, 0L);
		curl_easy_setopt(m_easyhandle, CURLOPT_HEADER, 0L);
		//curl_easy_setopt(m_easyhandle, CURLOPT_RESUME_FROM_LARGE, true);
		curl_easy_setopt(m_easyhandle, CURLOPT_APPEND, 1L);
	} else
	{
		//默认  启动覆盖上传任务	
		OutputDebugStringA("默认  启动覆盖上传任务\n");
		curl_easy_setopt(m_easyhandle, CURLOPT_APPEND, 0L);
	}
	m_nStatus=1;//设置“正在上传”状态
	code = curl_easy_perform(m_easyhandle);	
	curl_easy_cleanup(m_easyhandle);

	{
		boost::lock_guard<boost::mutex> l(g_ftp);
		fclose(file);
		m_bRun = false;
		m_bAbort = false;
	}

	bool bR;
	if(code!=0)
	{
		OutputDebugString(L"上传可能失败!");
		bR = false;
	} else {
		OutputDebugString(L"上传可能成功!");
		bR=true;
	}


	//Patch libcurl返回状态不准确的问题.begin
	OutputDebugString(L"Patch libcurl返回状态不准确的问题.begin\n");
	getRemoteFileInfo(std::string(pURL),m_fi);
	if( true==bR && 
		m_fi.filesize==oldRemoteFileSize && 
		m_filesize!=oldRemoteFileSize)
	{
		bR = false;
		OutputDebugString(L"Patch libcurl返回状态不准确的问题.修正为false!\n");
		std::wstring wsFN;
		if(uploadFilename==NULL)
		{
			wsFN=bufFileName;
			if(wsFN.find_last_of(L'//')!=-1)
				wsFN = wsFN.substr(wsFN.find_last_of(L'//')+1,wsFN.length());
			else if(wsFN.find_last_of(L'\\')!=-1)
				wsFN = wsFN.substr(wsFN.find_last_of(L'\\')+1,wsFN.length());				
		}
		else
		{
			wsFN = uploadFilename;
		}
		OutputDebugStringA("删除FTP上的文件!\n");
		deleteFile(wsFN.c_str());
	} else if( code==18 && 
		m_fi.filesize!=oldRemoteFileSize &&
		m_filesize==m_fi.filesize)
	{
		bR = true;
		OutputDebugString(L"Patch libcurl返回状态不准确的问题.修正为true!\n");
	}
	OutputDebugString(L"Patch libcurl返回状态不准确的问题.end\n");
	//Patch libcurl返回状态不准确的问题.end

	if(bR)
	{
		m_nStatus = 0;
	}
	else
	{
		m_nStatus = -1;

	    char msg[_CF_BUF_SIZE_];
		sprintf(msg,"uploadFile error code=%d\n",code);
		OutputDebugStringA(msg);
	}

	if(m_call) //回调
		m_call->done(bR);

	//不管上传有没有成功,上传后,重置m_fProgress(上传进度)
	m_fProgress = .0f;

	if (!bR)
		OutputDebugStringA(m_errbuf);

	return bR;
}

bool CCurlFTP::deleteFile(std::wstring fileName)
{
	char buf[MAX_PATH];
	memset(buf,0,sizeof(buf));
	w2c(fileName.c_str(),buf,fileName.length()*2+1);

	return deleteFile(std::string(buf));
}

bool CCurlFTP::deleteFile(std::string fileName)
{
	std::string sCmd("DELE ");

	sCmd = sCmd + fileName;
	struct curl_slist *headers=NULL; /* init to NULL is important */

	headers = curl_slist_append(headers, sCmd.c_str());
	m_easyhandle = curl_easy_init();
	curl_easy_setopt(m_easyhandle, CURLOPT_URL, m_ip);
	curl_easy_setopt(m_easyhandle, CURLOPT_USERPWD    , m_usrpwd);
	curl_easy_setopt(m_easyhandle, CURLOPT_ERRORBUFFER, m_errbuf);
	curl_easy_setopt(m_easyhandle, CURLOPT_QUOTE, headers);
	// curl_easy_setopt(easyhandle, CURLOPT_POSTQUOTE, headers); // 在数据传输之后操行删除操作
	CURLcode code = curl_easy_perform(m_easyhandle); /* transfer ftp data! */
	curl_slist_free_all(headers); /* free the header list */
	curl_easy_cleanup(m_easyhandle);

	bool bR = (code!=0)?false:true;

	if (!bR)
		OutputDebugStringA(m_errbuf);

	return bR;
}

bool CCurlFTP::deleteFolder(std::wstring foldername)
{
	char buf[MAX_PATH];
	memset(buf,0,sizeof(buf));
	w2c(foldername.c_str(),buf,foldername.length()*2+1);

	return deleteFolder(std::string(buf));
}

bool CCurlFTP::deleteFolder(std::string foldername)
{
	std::string sCmd("RMD ");

	sCmd = sCmd + foldername;
	struct curl_slist *headers=NULL; /* init to NULL is important */

	headers = curl_slist_append(headers, sCmd.c_str());
	m_easyhandle = curl_easy_init();
	curl_easy_setopt(m_easyhandle, CURLOPT_URL, m_ip);
	curl_easy_setopt(m_easyhandle, CURLOPT_USERPWD    , m_usrpwd);
	curl_easy_setopt(m_easyhandle, CURLOPT_ERRORBUFFER, m_errbuf);
	curl_easy_setopt(m_easyhandle, CURLOPT_QUOTE, headers);
	//curl_easy_setopt(m_easyhandle, CURLOPT_POSTQUOTE, headers); // 在数据传输之后操行删除操作
	CURLcode code = curl_easy_perform(m_easyhandle); /* transfer ftp data! */
	curl_slist_free_all(headers); /* free the header list */
	curl_easy_cleanup(m_easyhandle);

	bool bR = (code!=0)?false:true;

	if (!bR)
		OutputDebugStringA(m_errbuf);

	return bR;
}

bool CCurlFTP::createFolder(std::wstring foldername)
{
	char buf[MAX_PATH];
	memset(buf,0,sizeof(buf));
	w2c(foldername.c_str(),buf,foldername.length()*2+1);

	return createFolder(std::string(buf));
}

bool CCurlFTP::createFolder(std::string  foldername)
{
	std::string sCmd("MKD ");

	sCmd = sCmd + foldername;
	struct curl_slist *headers=NULL; /* init to NULL is important */

	headers = curl_slist_append(headers, sCmd.c_str());
	m_easyhandle = curl_easy_init();
	curl_easy_setopt(m_easyhandle, CURLOPT_URL, m_ip);
	curl_easy_setopt(m_easyhandle, CURLOPT_USERPWD    , m_usrpwd);
	curl_easy_setopt(m_easyhandle, CURLOPT_ERRORBUFFER, m_errbuf);
	curl_easy_setopt(m_easyhandle, CURLOPT_QUOTE, headers);
	//curl_easy_setopt(m_easyhandle, CURLOPT_POSTQUOTE, headers); // 在数据传输之后操行删除操作
	CURLcode code = curl_easy_perform(m_easyhandle); /* transfer ftp data! */
	curl_slist_free_all(headers); /* free the header list */
	curl_easy_cleanup(m_easyhandle);

	bool bR = (code!=0)?false:true;

	if (!bR)
		OutputDebugStringA(m_errbuf);

	return bR;
}

int CCurlFTP::isAbilityConn()
{
	m_easyhandle = curl_easy_init();
	curl_easy_setopt(m_easyhandle, CURLOPT_URL, m_ip);
	curl_easy_setopt(m_easyhandle, CURLOPT_USERPWD    , m_usrpwd);
	curl_easy_setopt(m_easyhandle, CURLOPT_ERRORBUFFER, m_errbuf);
	curl_easy_setopt(m_easyhandle, CURLOPT_TIMEOUT_MS,3000);

	CURLcode code = curl_easy_perform(m_easyhandle); 

	if(code>=0)
		curl_easy_cleanup(m_easyhandle);

	m_isAbilityConn = code;

	return m_isAbilityConn;
}

bool CCurlFTP::isSupportREST()
{
	std::string sCmd("REST 100");
	struct curl_slist *headers=NULL; // init to NULL is important 

	headers = curl_slist_append(headers, sCmd.c_str());
	m_easyhandle = curl_easy_init();
	curl_easy_setopt(m_easyhandle, CURLOPT_URL, m_ip);
	curl_easy_setopt(m_easyhandle, CURLOPT_USERPWD    , m_usrpwd);
	curl_easy_setopt(m_easyhandle, CURLOPT_ERRORBUFFER, m_errbuf);
	curl_easy_setopt(m_easyhandle, CURLOPT_QUOTE, headers);
	CURLcode code = curl_easy_perform(m_easyhandle); 
	curl_slist_free_all(headers); // free the header list
	curl_easy_cleanup(m_easyhandle);

	bool bR = code==0?true:false;

	if (!bR)
		OutputDebugStringA(m_errbuf); OutputDebugStringA("\n");

	return bR;
}

bool CCurlFTP::getRemoteFileInfo(std::string url,CCurlFTP_FILE_INFO &FileInfo)
{
	CURL *curl;
	CURLcode res;

	FileInfo.urlFileName = url;

	m_easyhandle = curl_easy_init();
	if(m_easyhandle) {
		curl_easy_setopt(m_easyhandle, CURLOPT_URL, url.c_str());
		curl_easy_setopt(m_easyhandle, CURLOPT_USERPWD    , m_usrpwd);
		/* No download if the file */ 
		curl_easy_setopt(m_easyhandle, CURLOPT_NOBODY, 1L);
		/* Ask for filetime */ 
		curl_easy_setopt(m_easyhandle, CURLOPT_FILETIME, 1L);
		/* No header output: TODO 14.1 http-style HEAD output for ftp */ 
		curl_easy_setopt(m_easyhandle, CURLOPT_HEADERFUNCTION, throw_away);
		curl_easy_setopt(m_easyhandle, CURLOPT_HEADER, 0L);
		/* Switch on full protocol/debug output */ 
		/* curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); */ 
		
		curl_easy_setopt(m_easyhandle, CURLOPT_ERRORBUFFER, m_errbuf);

		res = curl_easy_perform(m_easyhandle);
		if(CURLE_OK == res) {
			res = curl_easy_getinfo(m_easyhandle, CURLINFO_FILETIME, &FileInfo.filetime);
			///if((CURLE_OK == res) && filetime) {...}
			res = curl_easy_getinfo(m_easyhandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &FileInfo.filesize);
			//if((CURLE_OK == res) && (filesize>0)) {...}
		} 
		/* always cleanup */ 
		curl_easy_cleanup(m_easyhandle);
	}	

	if(CURLE_OK == res) 
		return true;
	return false;
}

bool CCurlFTP::isFileExist(wchar_t * filename)
{
	if(_waccess(filename, 0) == 0)
		return true;
	return false;
}

bool CCurlFTP::isFileRead(wchar_t * filename)
{
	if(_waccess(filename, 4) == 0)
		return true;
	return false;
}

void CCurlFTP::abort()
{
	if(m_bRun)
		m_bAbort = true;
}

char * CCurlFTP::makeFullName(char *ip,wchar_t * filename,wchar_t * uploadFilename)
{
	static char cR[_CF_BUF_SIZE_];
	
	int  nPos = strlen(ip);

	std::wstring wsFN=filename;
	if(wsFN.find_last_of(L'//')!=-1)
		wsFN = wsFN.substr(wsFN.find_last_of(L'//')+1,wsFN.length());
	else if(wsFN.find_last_of(L'\\')!=-1)
		wsFN = wsFN.substr(wsFN.find_last_of(L'\\')+1,wsFN.length());

	memset(cR,0,sizeof(cR));	
	strncpy(cR,ip,sizeof(cR));
	cR[nPos]='/';

	//拼接字符串
	char buf[_CF_BUF_SIZE_];
	memset(buf,0,sizeof(buf));
	if (uploadFilename==NULL)
		w2c(wsFN.c_str(),buf,wsFN.length()*2+1);
	else
		w2c(uploadFilename,buf,wcslen(uploadFilename)*2+1);
	
	strncpy((cR+nPos+1),buf,_CF_BUF_SIZE_-nPos);

	return cR;
}

char *CCurlFTP::w2c(const wchar_t *pwstr,char *pcstr, size_t len)
{
	int nlength=wcslen(pwstr);

	//获取转换后的长度
	int nbytes = WideCharToMultiByte( 0, // specify the code page used to perform the conversion
		0,         // no special flags to handle unmapped characters
		pwstr,     // wide character string to convert
		nlength,   // the number of wide characters in that string
		NULL,      // no output buffer given, we just want to know how long it needs to be
		0,
		NULL,      // no replacement character given
		NULL );    // we don't want to know if a character didn't make it through the translation

	// make sure the buffer is big enough for this, making it larger if necessary
	if(nbytes>len)   nbytes=len;

	// 通过以上得到的结果,转换unicode 字符为ascii 字符
	WideCharToMultiByte( 0, // specify the code page used to perform the conversion
		0,         // no special flags to handle unmapped characters
		pwstr,   // wide character string to convert
		nlength,   // the number of wide characters in that string
		pcstr, // put the output ascii characters at the end of the buffer
		nbytes,                           // there is at least this much space there
		NULL,      // no replacement character given
		NULL );

	return pcstr ;
}


 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kagula086

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值