Qtir Qt: имена файлов, отбрасывающие не-Ascii символы

У меня проблемы с QDir, теряющим не-Ascii символы из имен моих файлов.

У меня есть файлы с именами, такими как testingöäüß.txt или exampleΦ.shp, и при попытке использовать утилиты Qt, такие как QDir и QFile, они просто отображаются как 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 просто не справится с этим? Спасибо!

2 ответа

Я знаю, что это старый вопрос, но я столкнулся с той же проблемой. Тот же самый точный код Qt будет хорошо работать на моей виртуальной машине разработки, но когда я перенес его в встроенную систему Linux (работающую на x86, в буквальном смысле на тот же исполняемый файл), в именах моих каталогов просто молча пропали символы, не входящие в ASCII.

Оказалось, QTextCodec::codecForLocale на моей виртуальной машине dev был установлен UTF-8и на встроенной коробке это было System, Если я вручную изменил локаль на UTF-8, прежде чем делать какие-либо операции с файловой системой (вызывая QTextCodec::codecForName("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
}

Если вы до сих пор их не видите, это потому, что настройки вашей консоли не позволяют их отображать. Попробуйте записать их в файл или отобразить в графическом интерфейсе - или просто попробуйте открыть файл с таким именем, он будет работать.

Другие вопросы по тегам