代码之家  ›  专栏  ›  技术社区  ›  JosanSun

为什么我在关于文件编码格式的qt代码中得到了凌乱的代码结果?

  •  0
  • JosanSun  · 技术社区  · 6 年前

    我最近想学习qt如何对文件进行编码和解码。我测试了一些例子,但有些让我感到困惑。

    这是我的代码:

    #include <QApplication>
    #include <QFile>
    #include <QTextStream>
    
    #define TEST(testFile) void test##testFile()
    
    TEST(ANSI)
    {
        QFile inFile(":/test/test-ANSI.txt");
        if (!inFile.open(QIODevice::ReadOnly | QIODevice::Text))
            return;
    
        QFile outFile("../test-ANSI-bak.txt");
        if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
            return;
    
        QTextStream in(&inFile);
        QTextStream out(&outFile);
        out.setCodec("UTF-8");
    
        // 这样写入会去掉换行符号
        while (!in.atEnd()) {
            QString line = in.readLine();
            out << line;
        }
    }
    
    TEST(GB2312)
    {
        QFile inFile(":/test/test-GB2312.txt");
        if (!inFile.open(QIODevice::ReadOnly | QIODevice::Text))
            return;
    
        QFile outFile("../test-GB2312-bak.txt");
        if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
            return;
    
        QTextStream in(&inFile);
        QTextStream out(&outFile);
        out.setCodec("UTF-8");
    
        while (!in.atEnd()) {
            QString line = in.readLine();
            out << line;
        }
    }
    
    TEST(utf8BOM)
    {
        QFile inFile(":/test/test-utf8-BOM.txt");
        if (!inFile.open(QIODevice::ReadOnly | QIODevice::Text))
            return;
    
        QFile outFile("../test-utf8-BOM-bak.txt");
        if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
            return;
    
        QTextStream in(&inFile);
        QTextStream out(&outFile);
        out.setCodec("UTF-8");
    
        while (!in.atEnd()) {
            QString line = in.readLine();
            out << line;
        }
    }
    
    TEST(utf8)
    {
        QFile inFile(":/test/test-utf8.txt");
        if (!inFile.open(QIODevice::ReadOnly | QIODevice::Text))
            return;
    
        QFile outFile("../test-utf8-bak.txt");
        if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
            return;
    
        QTextStream in(&inFile);
        QTextStream out(&outFile);
        out.setCodec("UTF-8");
    
        while (!in.atEnd()) {
            QString line = in.readLine();
            out << line;
        }
    }
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        testANSI();
        testGB2312();
        testutf8BOM();
        testutf8();
    
        return app.exec();
    }
    

    我的输入文本内容如下:

    ----
    I love you!
    我爱你!
    。。。
    1234
    1234
    

    对于ANSI、GB2312、utf8 BOM,我得到了输出文件 例如:测试ANSI bak。txt文件

    ----I love you!我爱你!。。。12341234
    

    对于utf8,我得到了输出文件 例如:test-utf8-bak。txt文件

    ----I love you!鎴戠埍浣狅紒銆傘€傘€12341234
    

    为什么test-utf8-bak。txt显示凌乱的代码?我很困惑!

    1 回复  |  直到 6 年前
        1
  •  3
  •   Alan Birtles    6 年前

    QTextStream 正在根据输入文件的内容猜测编解码器,对于它错误猜测的非BOM utf-8文件。

    你应该打电话 in.setCodec() 如果知道输入文件的格式,如果不知道格式,则必须继续依赖Qt的猜测或编写自己的编码检测器。

    看起来QTextStream只查找BOM表,不进行任何其他Unicode检测,从 http://doc.qt.io/qt-5/qtextstream.html :

    还支持自动Unicode检测。启用此功能时(默认行为),QTextStream将检测UTF-16或UTF-32 BOM(字节顺序标记),并在读取时切换到适当的UTF编解码器