4

我遇到了 QDir 从我的文件名中丢失非 Ascii 字符的问题。

我的文件名称如 testingöäüß.txt 或 exampleΦ.shp,当尝试使用 QDir 和 QFile 等 Qt 实用程序时,它们只是显示为 testing.txt 和 example.shp。好像我无法告诉这些类使用哪种编码。我正在尝试 QDirIterator 和 QDir 函数 entryInfoList:

   QDir someDir("/home/blah");  //contains testingöäüß.txt

   QDirIterator dirIter(someDir.absolutePath(), QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);
   while(dirIter.hasNext())
   {
      QString fileName1 = QFile::decodeName(dirIter.next().toUtf8());
      std::cout << "QDirIterator Name " << fileName1.toStdString().c_str() << std::endl;
   }

   QFileInfoList fileInfoList = someDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);
   foreach(QFileInfo fileInfo, fileInfoList)
   {
      QString fileName1 = QFile::decodeName(fileInfo.fileName().toUtf8());
      std::cout << "entryInfoList Name " << fileName1.toStdString().c_str() << std::endl;

      QString fileName2 = QFile::decodeName(fileInfo.absoluteFilePath().toUtf8());
      std::cout << "entryInfoList Name2 " << fileName2.toStdString().c_str() << std::endl;

      QString fileName3 =  QString::fromUtf8(dirIter.fileInfo().absoluteFilePath().toStdString().c_str());
      std::cout << "entryInfoList Name3 " << fileName3.toStdString().c_str() << std::endl;
   }

这些印刷品中的每一张都将缺少非 ascii 字符。似乎一旦您尝试获取要循环的文件名,它们将仅是 ascii。有人对此有任何想法吗?或者 Qt 不能处理这个?谢谢!

4

2 回答 2

4

我知道这是一个老问题,但我遇到了同样的问题。完全相同的 Qt 代码在我的开发 VM 上可以正常工作,但是当我将它转移到嵌入式 Linux 系统(在 x86 上运行,所以实际上是相同的可执行文件)时,我的目录名称只是默默地删除了它们的非 ASCII 字符。

原来QTextCodec::codecForLocale我的开发虚拟机上的设置为UTF-8,而在嵌入式盒子上它是System。如果我在执行任何文件系统操作(通过调用QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")))之前手动将语言环境更改为 UTF-8,一切都开始正常工作。

那么为什么会发生这种情况呢?我的怀疑是,在精简嵌入式系统的根文件系统的过程中,我可能不小心删除了 Qt 用来尝试自动检测语言环境的一些与语言环境相关的文件。当它无法确定它是在 UTF-8 上时,它会退回到 System,无论出于何种原因,它都已损坏(可能出于同样的原因,它一开始就无法检测到 UTF-8)。

我最终需要修复导致它无法自动检测的任何问题,但在短期内,如果您遇到同样的问题,手动设置 UTF-8 语言环境应该可以工作。

请注意,这与控制台是否可以显示 UTF-8 无关,也与手动将 UTF-16 转换为 UTF-8 无关!所以菲利克斯对这​​个问题的回答是不正确的,至少对于这个特定的问题。为了从等式中完全删除控制台的功能,我还简单地打印了字符串中 UTF-16 字符的数量,并且每个非 ASCII 字符实际上使 QDir::entryInfoList 返回的路径和文件名字符串少了一个UTF-16 字符。此外,致命的赠品是角色被简单地剥离了,而不仅仅是用垃圾或问号或其他东西代替。

于 2017-05-07T15:36:31.663 回答
0

Qt 可以处理带有特殊字符的文件名。你只是让它们在那个字符串转换的东西中消失。(这完全没有必要)试试这种方式:

#include <QDebug>
//...
QFileInfoList fileInfoList = someDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);
foreach(QFileInfo fileInfo, fileInfoList)
{
    qDebug() << fileInfo.fileName();//uses qdebug
    std::cout << fileInfo.fileName().toStdWString() << std::endl;//uses a 16Bit string on normal cout
}

如果您仍然看不到它们,那是因为您的控制台设置不允许显示它们。尝试将它们写入文件或在 gui 中显示它们 - 或者只是尝试打开具有该名称的文件,它会起作用。

于 2016-02-13T09:54:55.683 回答