Qt FTP地址下载中文乱码问题


前言

最近在做Qt项目,使用FTP下载,需要存储ftp地址,ftp地址中文直接复制出现乱码如下:
正常:ftp://127.0.0.1/公共资料区
复制:ftp://127.0.0.1/%E5%85%AC%E5%85%B1%E8%B5%84%E6%96%99%E5%8C%BA


一、为什么乱码?

FTP使用URL的格式记录地址,将中文编码成%形式,可以查看url编码,网上有url编码在线工具很方便查看。

二、解决办法

1.使用QUrl的编码和解码函数

QUrl::fromPercentEncoding(tmp_ba);
QUrl::toPercentEncoding(tmpStrFtpAddr, “😕%”);
经过摸索直接用似乎有点问题于是各种百度最后编写自己的解码函数(url编码–>中文)

QString MainWindow::DecodeURL(QString StrFtpAddr) {
    bool haveChinese = StrFtpAddr.contains(QRegExp("[\\x4e00-\\x9fa5]+"));//判断是否有中文,有中文说明不用转化,不是url编码
    if (!haveChinese) {
        QByteArray tmp_ba = StrFtpAddr.toLocal8Bit();
        tmp_ba = tmp_ba.toPercentEncoding(":/%");
        QString tmpStrFtpAddr = QUrl::fromPercentEncoding(tmp_ba);
        QString tmpStrFtpAddr2 = QUrl::toPercentEncoding(tmpStrFtpAddr, ":/%");
        if (tmpStrFtpAddr2 == StrFtpAddr) {
        } else {
            tmpStrFtpAddr = FromSpecialEncoding(StrFtpAddr);
            //qDebug() << tmpStrFtpAddr2;
        }
        return tmpStrFtpAddr;
    } else {
        return StrFtpAddr;
    }
}

2.使用时遇到的其他问题

ftp中文地址->url方式编码地址有两种:
中文:公共资料区
1.utf8中文->url编码:%E5%85%AC%E5%85%B1%E8%B5%84%E6%96%99%E5%8C%BA
2.gbk中文->url编码:%B9%AB%B9%B2%D7%CA%C1%CF%C7%F8
可以看到gbk,utf8编码的中文对应url地址不一样,这样url解码时需要判断时gbk的方式还是utf8的方式。
我这里就简单的先使用utf8方式解码再编码(str->utf8解码=中文str,中文str->utf8编码),对比前后的是不是一样的来判断是否为utf8中文,(qt url编码按照utf8来编码的)然后在进行gbk-utf8转码
以下函数实现自动识别(gbk或utf8)url编码,并转化为中文utf8格式

QString MainWindow::DecodeURL(QString StrFtpAddr) {
    bool haveChinese = StrFtpAddr.contains(QRegExp("[\\x4e00-\\x9fa5]+"));
    if (!haveChinese) {
        QByteArray tmp_ba = StrFtpAddr.toLocal8Bit();
        tmp_ba = tmp_ba.toPercentEncoding(":/%");
        QString tmpStrFtpAddr = QUrl::fromPercentEncoding(tmp_ba);
        QString tmpStrFtpAddr2 = QUrl::toPercentEncoding(tmpStrFtpAddr, ":/%");
        if (tmpStrFtpAddr2 == StrFtpAddr) {
        } else {
            tmpStrFtpAddr = FromSpecialEncoding(StrFtpAddr);
            //qDebug() << tmpStrFtpAddr2;
        }
        return tmpStrFtpAddr;
    } else {
        return StrFtpAddr;
    }
}

//将gbk编码的字符串改为UTF-8编码,在获取FTP服务器下文件时使用
QString MainWindow::FromSpecialEncoding(QString str) {
    QByteArray array;
    for (int i = 0; i < str.length();) {
        if (0 == QString::compare(str.mid(i, 1), QString("%"))) {
            if ((i + 2) < str.length()) {
                array.append(str.mid(i + 1, 2).toShort(0, 16));
                i = i + 3;
            } else {
                array.append(str.mid(i, 1));
                i++;
            }
        } else {
            array.append(str.mid(i, 1));
            i++;
        }
    }
    QTextCodec *code = QTextCodec::codecForName("GBK");
    //QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
    return code->toUnicode(array);
    //return utf8->fromUnicode(code->toUnicode(array));
}

使用ftp地址时,再将保存的中文进行编码,可能遇到url解码出现很多%25问题,下面函数可以解决

/*ftp下载文件*/
void MyFtpOp::ftpDownload(const QString &fileName)
{
    QFileInfo info;
    info.setFile(fileName);

    m_file.setFileName(fileName);
    m_file.open(QIODevice::WriteOnly | QIODevice::Append);
    m_manager = new QNetworkAccessManager(this);
    m_manager->setNetworkAccessible(QNetworkAccessManager::Accessible);
    /*ftp地址编码转换*/
    mFtpPath = DecodeURL(mFtpPath);

    m_url.setPath(ToSpecialEncoding(mFtpPath));
    qDebug() << m_url;
    pReply = m_manager->get(QNetworkRequest(m_url));

    connect(pReply, SIGNAL(readyRead()), this, SLOT(readContent()));
    connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    connect(pReply, SIGNAL(downloadProgress(qint64, qint64)), this, SIGNAL(downloadProgress(qint64, qint64)));
    connect(pReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SIGNAL(error(QNetworkReply::NetworkError)));
}

//将UTF-8编码的字符串改为gbk编码,在由客户端上传或下载文件时使用
QString MyFtpOp::ToSpecialEncoding(const QString &InputStr)
{
#ifdef Q_OS_WIN
    return QString::fromLatin1(InputStr.toLocal8Bit());
#else
    QTextCodec *codec= QTextCodec::codecForName("gbk");
    if (codec)
    {
        return QString::fromLatin1(codec->fromUnicode(InputStr));
    }
    else
    {
        return QString("");
    }
#endif
}

总结

了解:1.Url编码方式gbk,utf8两种;2.gbk-utf8转码
自己各种百度花了不少时间,留个笔记
时间:2022.04.14

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值