QSettings的编码问题(QTBUG15543、QTBUG19552)

我们在QSettings 与中文 一文中认识了QSettings在Qt4.5中引入的setIniCodec成员函数。

这是一个挺不错的函数,估计解决了不少人的中文(我自己几乎不在里面用中文,感受不是太深)。

这两天看Qt的bugreport,发现这个看似无害的便利函数还是直接导致了一些 bug:

QTBUG15543

是一个这样的问题:

  • 一个长度为256的QByteArray对象(存放"/x0/x1/x2.../x255")
  • 将该对象通过设置了编码的QSettings写入ini文件后,内容不对!
    • 当然更无法正确读入了
  • 如果不设置编码的话,写入和读出的内容是一致的(也就是工作正常)。

bug提交者给出的代码如下:

#include 
#include 
#include 

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    {
        QSettings set("settings.ini",QSettings::IniFormat,0);
        set.setIniCodec("cp1251");
        QByteArray ba;
        ba.resize(256);
        for(int i=0;i原因 
  

我们在QSettings 与中文 一文中涉及到这部分内容。

  • QSettings 的核心是 一个QMap ,key是一个QString,value是QVariant类型

  • 将value写入文件的过程分两步
    • 将 QVariant 变成 QString 或 QStringList
    • 将字符串和字符串列表序列化(字符转义、解码等)得到QByteArray字节流

回头看这个bug:

  • QByteArray 对象存放在QVariant中,第一步先变成QString:@ByteArray(.....)

    • 括号内是QByteArray的真实内容"/x0/x1/x2.../x255" 对应的字符串。其实这是通过QString::fromLatin1()实现的

  • 将该字符串转义并采用指定的codec进行编码
    • 问题出来了:cp1251 无法对U+128U+129 等unicode字符进行解码,于是问号被写入了ini文件。

bug的修复:

  • 这个应该还算比较简单,只要保证对于QByteArray不进行编码即可(当然,对于其他一些自定义的类型,会变成字符串Variant(...),也不能进行编码)

QTBUG-19552

是这样一个问题:

  • 用未设置codec的QSettings读入一个ini文件
  • 销毁该 QSettings 对象
  • 用设置了codec的QSettings重现读入该ini文件
  • 设置的编码不起作用

bug 提交者给出的代码如下

#include 
#include 
#include 

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QString v;
    {
        QSettings settings("test1.ini", QSettings::IniFormat);
        v = settings.value("lang").toString();
    }
    QSettings settings1("test1.ini", QSettings::IniFormat);
    settings1.setIniCodec("UTF-8");
    QString v1 = settings1.value("lang").toString();

    return 0;
}

原因

QSettings 应该是处于性能上的考虑,会对读入的ini文件内容进行缓存。

这个bug产生的原因是:

  • 上一个对象销毁时,读入的ini的内容被缓存了
  • 新创建QSettings对象时,发现缓存中有数据,不会再读取文件。于是编码将不会起作用。

如何修复:不太清楚该如何做,或许

  1. 禁用掉这个缓存,这个是最简单的,修改的代码比较少。只要QSettings销毁时不将配置文件内容放入 unusedCache 这个全局静态的QCache对象即可。
  2. 当设置 codecs 的时候,设置一个dirty 标记,这样一来,在使用QSettings时可以强制读取文件。

参考

  • http://bugreports.qt.nokia.com/browse/QTBUG-15543

  • http://bugreports.qt.nokia.com/browse/QTBUG-19552

 

你可能感兴趣的:(QTBUG,Qt,codec,ini,qt,工作)