libcurl ftp上传中文路径问题

发布于:2025-02-11 ⋅ 阅读:(29) ⋅ 点赞:(0)

最近我在使用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,这里需要替换为实际的URL
             QString remotePath_Modified=remotePath;

             QString fullFtpUrl = QString("%1%2").arg(HostUrl, remotePath_Modified);

             // 将 QString 转换为 GBK 编码的 QByteArray
             QTextCodec *codec = QTextCodec::codecForName("GBK");
             QByteArray fullFtpUrlEncoded = codec->fromUnicode(fullFtpUrl);

             // 将 QByteArray 转换为 char*
             const char* fullFtpUrlCStr = fullFtpUrlEncoded.constData();

             // 设置 CURLOPT_URL
             curl_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;
 }