我在 QDir 丢失文件名中的非 ASCII 字符时遇到问题。
我有名称为testingöäüß或exampleΦ.shp的文件.txt当尝试使用QDir和QFile等Qt实用程序时,它们只是显示为testing.txt和example.shp。似乎我无法告诉这些类使用哪种编码。我正在尝试QDirIterator和QDir函数条目InfoList:
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根本无法处理这个问题吗?谢谢!
这是一个老问题,但我刚刚遇到了同样的问题。相同的Qt代码在我的开发VM上可以正常工作,但是当我将其转移到嵌入式Linux系统(在x86上运行,因此实际上是相同的可执行文件(时,我的目录名称只是默默地删除了它们的非ASCII字符。
原来我的开发 VM 上的QTextCodec::codecForLocale
设置为 UTF-8
,而在嵌入式框中System
。如果我在执行任何文件系统操作(通过调用 QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"))
(之前手动将语言环境更改为 UTF-8,则一切开始正常工作。
那么,为什么会发生这种情况呢?我的怀疑是,在精简嵌入式系统的根文件系统的过程中,我可能不小心删除了一些与语言环境相关的文件,Qt正在使用这些文件来尝试自动检测语言环境。当它无法确定它是否在 UTF-8 上时,它会回退到系统,无论出于何种原因,系统都会被破坏(也许出于同样的原因,它一开始就无法检测到 UTF-8(。
我最终需要修复导致它无法自动检测的任何内容,但是如果您遇到同样的问题,在短期内只需手动设置 UTF-8 语言环境就可以了。
请注意,这与控制台是否可以显示 UTF-8 无关,也与手动将 UTF-16 转换为 UTF-8 无关!所以菲利克斯对这个问题的回答是不正确的,至少在这个特定问题上是这样。为了从等式中完全删除控制台的功能,我还简单地打印了字符串中 UTF-16 字符的数量,并且每个非 ASCII 字符实际上都使从 QDir::entryInfoList 返回的路径和文件名字符串少了一个 UTF-16 字符。此外,致命的赠品是角色被简单地剥离了,而不仅仅是用垃圾或问号或其他任何东西代替。
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 显示它们 - 或者只是尝试打开具有该名称的文件,它将起作用。