最近我在使用libcurl库开发ftp客户端的时候,遇到了一个问题,部分ftp服务器不支持中文路径,后来研究了一下,发现是因为ftp服务器的编码问题,例如filezilla Server采用UTF-8编码,这很好,几乎不会遇到编码格式的问题。ServU,尤其是老版本大多采用gbk编码,我在编写代码时就遇到中文路径无法处理的情况,下面是我的解决思路。
我本地代码默认是UTF-8编码格式,转换远程ftp路径的编码格式,强制转换为gbk编码,同理,如果代码中默认是gbk编码,遇到无法上传的问题,那就强制转换为UTF-8编码格式:
// 将 QString 转换为 GBK 编码的 QByteArray
QTextCodec *codec = QTextCodec::codecForName("GBK");
QByteArray fullFtpUrlEncoded = codec->fromUnicode(fullFtpUrl);// 将 QByteArray 转换为 char*
const char* fullFtpUrlCStr = fullFtpUrlEncoded.constData();
完整FTP上传代码:
// FTP上传回调函数
static size_t read_callback(void *ptr, size_t size, size_t nmemb, FILE *stream)
{return fread(ptr, size, nmemb, stream);
}
bool uploadFile(const QString& localPath,const QString& remotePath)
{bool flag=false;CURL *curl;CURLcode res;QFileInfo fileInfo(localPath);curl_global_init(CURL_GLOBAL_ALL);curl = curl_easy_init();if (curl){std::wstring wFilePath = localPath.toStdWString(); // 转换为宽字符串FILE *file = _wfopen(wFilePath.c_str(), L"rb"); // 使用 _wfopen 打开文件if (file){// 设置FTP URL,这里需要替换为实际的URLQString remotePath_Modified=remotePath;QString fullFtpUrl = QString("%1%2").arg(HostUrl, remotePath_Modified);// 将 QString 转换为 GBK 编码的 QByteArrayQTextCodec *codec = QTextCodec::codecForName("GBK");QByteArray fullFtpUrlEncoded = codec->fromUnicode(fullFtpUrl);// 将 QByteArray 转换为 char*const char* fullFtpUrlCStr = fullFtpUrlEncoded.constData();// 设置 CURLOPT_URLcurl_easy_setopt(curl, CURLOPT_URL, fullFtpUrlCStr);curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);curl_easy_setopt(curl,CURLOPT_USERNAME,UserName.toStdString().c_str());curl_easy_setopt(curl,CURLOPT_PASSWORD,UserPassword.toStdString().c_str());curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);curl_easy_setopt(curl, CURLOPT_READDATA, file);curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fileInfo.size());curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);// 启用详细日志记录curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);// 使用被动模式curl_easy_setopt(curl, CURLOPT_FTPPORT, "-");// 执行FTP上传res = curl_easy_perform(curl);// 检查错误if (res != CURLE_OK){qDebug() << "FTP upload failed:" << curl_easy_strerror(res);flag=false;} else {flag=true;qDebug() << "FTP upload successful!";}fclose(file);} else {flag=false;qDebug() << "Failed to open file for reading:" << fileInfo.absoluteFilePath();}// 清理curl_easy_cleanup(curl);}curl_global_cleanup();return flag;}