QT 中使用QFile如何识别txt文件的编码格式:utf-8 ANSI

系列文章目录

前言

小弟我在在上一篇Qt中QFile类读取ansi编码格式txt文件,在QTextEdit控件中显示乱码
文章中聊到如何读取ANSI和UFT-8文件,但有个前提是首先知道txt文件的编码格式,如何程序中我们事先不知道txt文件的编码格式那我们怎么做呢?下面我和大家就来聊聊如何判断文件的编码格式

一、判断txt文件编码格式

Qt提供了一个类QTextCodec类,专门用来对字符串进行不同编码方式的转换。
其中重要的两个静态方法是:fromUnicode和toUnicode。
通过这两个静态方法可以将其他类型(如gbk)的字符串转换为utf-8字符串(采用toUnicode),或者将utf-8的字符串转换为其他类型(如gbk)的字符串(采用fromUnicode)。
基本原理是:拿到一定长度的 字节流 然后判断含有哪些 byte 就知道是什么东西了,如果是文本文件,先尝试读前两个字节,看是否是BOM,windows,Qt对字符串默认是采用utf-8编码的,如果要打开gbk的文件,依然采用utf-8编码的话,当然就不识别了,显示就是乱码。
读取txt文件时,很多时候无法获取文件的编码格式.如果直接进行使用,则有可能出现乱码.需要在使用前将其转为Unicode(Qt的默认编码格式). 虽然实际的编码格式种类非常多,但平常主要使用的有GBK与UTF-8两种.可以依次尝试转换,如果转换出现无效字符则认为不是该种编码格式. QString GetCorrectUnicode(const QByteArray &ba) { QTextCodec::ConverterState state; QTextCodec *codec = QText

二、解决方法

enum class EncodingFormat : int
{
    ANSI = 0,//GBK
    UTF16LE,
    UTF16BE,
    UTF8,
    UTF8BOM,
};
EncodingFormat ProjectWin::FileCharacterEncoding(const QString &fileName)
{
    //假定默认编码utf8
    EncodingFormat code = EncodingFormat::UTF8;

    QFile file(fileName);
    if (file.open(QIODevice::ReadOnly))
    {
            //读取3字节用于判断
            QByteArray buffer = file.read(3);
            quint8 sz1st = buffer.at(0);
            quint8 sz2nd = buffer.at(1);
            quint8 sz3rd = buffer.at(2);
            if (sz1st == 0xFF && sz2nd == 0xFE)
            {
                code = EncodingFormat::UTF16LE;
            }
            else if (sz1st == 0xFE && sz2nd == 0xFF)
            {
                code = EncodingFormat::UTF16BE;
            }
            else if (sz1st == 0xEF && sz2nd == 0xBB && sz3rd == 0xBF)
            {
                code = EncodingFormat::UTF8BOM;
            }
            else
            {
                //尝试用utf8转换,如果无效字符数大于0,则表示是ansi编码
                QTextCodec::ConverterState cs;
                QTextCodec* tc = QTextCodec::codecForName("utf-8");
                tc->toUnicode(buffer.constData(), buffer.size(), &cs);
                code = (cs.invalidChars > 0) ? EncodingFormat::ANSI : EncodingFormat::UTF8;
            }

            file.close();
    }

    return code;
}

具体使用

void ProjectWin::readParaFile(QString filePath)
{
//读取ansi编码格式文件
    m_paraText->clear();
    if (!m_paraText) {
        qDebug() << "m_paraText is null!";
        return;
    }

//    filePath = "E:/work/ImageManageSys/utf8/0000_051623_162252_05_004_00001_00008_00.txt";
    EncodingFormat code = FileCharacterEncoding(filePath);
    qDebug() << "code=" << (int)code;

	//读取ANSI编码格式文件
    if(code == EncodingFormat::ANSI)
    {
        QString txtFile = filePath.left(filePath.size() -3);
        txtFile += "txt";
    //
        QFile file(filePath);
        if(file.open(QIODevice::ReadOnly)) {
    //        qDebug() << file.errorString();
            QTextCodec::setCodecForLocale(QTextCodec::codecForName("gb2312"));//中文转码声明
            QString temStr;
            while(!file.atEnd())
            {
                    QByteArray arr = file.readAll();
                    arr.replace(0x0B,0x0D);
                    temStr = QString::fromLocal8Bit(arr, arr.length());//Window下的QByteArray转QString
                    m_paraText->append(temStr);
            }

            //读取任务号
            while (!file.atEnd())
            {
               QString line = file.readLine();
               if(line.contains(u8"任务代号:", Qt::CaseSensitive))
                {
                    int pos = line.lastIndexOf(":");
                    QString taskNum = line.right(line.size() - pos - 2);
                    taskNum = taskNum.trimmed();
                    m_taskNumSet.insert(taskNum);
                    break;
                }
            }
        }
           file.close();
    }
    
    //读取UTF-8编码格式文件
    if(code == EncodingFormat::UTF8)
    {
       //读取utf8编码格式
       m_paraText->clear();
           if (!m_paraText) {
               qDebug() << "m_paraText is null!";
               return;
           }



           QString txtFile = filePath.left(filePath.size() -3);
           txtFile += "txt";
           QFile file(filePath);
           if(!file.open(QIODevice::ReadOnly)) {
               qDebug() << file.errorString();
           }



           QTextStream in(&file);
           in.setCodec("UTF-8");  // 设置编码为UTF-8

           QString chineseText;


           while(!in.atEnd()) {
               QString line = in.readLine();


               if(line.contains(u8"任务代号:", Qt::CaseSensitive))
               {
                   int pos = line.lastIndexOf(":");
                   QString taskNum = line.right(line.size() - pos - 2);
                   taskNum = taskNum.trimmed();
                   m_taskNumSet.insert(taskNum);
       //            break;
               }



               m_paraText->append(line); // 添加到QTextEdit控件中
           }

           file.close();
    }
}

三、参考

hellokandy

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值