Details
-
Bug
-
Resolution: Won't Do
-
P2: Important
-
None
-
5.11.3, 6.0.0 Beta2
-
it has no concern with the platform but only concern with Qt Version.
Description
I have met a problem that I can not iterator some files by using QDir, and the invisible files could be listed in terminal, which terminal is not based on Qt.
The file manager on linux such as Nautilus, Nemo, etc, do not iterator files by QDir, and can list the files and mark it 'invalid codec'.
I tested this on Qt 5.9 and Qt 5.11, and Qt 6.0. Qt 5.9 works fine while 5.11 and 6.0 do not show the files which have a invalid codec name, and I found that it is caused by the codec of the name. the code below is in version 5.11, and it has changed in Qt 6.0, but the result is the same, couldn't list the files too.
// qfilesystemiterator_unix.cpp bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) { if (!dir) return false; for (;;) { dirEntry = QT_READDIR(dir); if (dirEntry) { // process entries with correct UTF-8 names only // this condition is added by purpose, and it cause this problem i mentioned, i'm wondering if it is too rude to filter files here? maybe you should give a flag or something that i can manage wether to filter it by my self. this is the reason why i cannot iterator the files which have some codec error. if (QFile::encodeName(QFile::decodeName(dirEntry->d_name)) == dirEntry->d_name) { fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name), QFileSystemEntry::FromNativePath()); metaData.fillFromDirEnt(*dirEntry); return true; } } else { break; } } lastError = errno; return false; }
here is the result:
my application is based on qt, and iterator files using qdir, do not work well in this case.
this is the nautilus and nemo, which could list the files though marked as "wrong codec", this is what i wanted, three of them all in the same directory:
in Qt 6.0, the code is
static bool checkNameDecodable(const char *d_name, qsizetype len) { // This function is called in a loop from advance() below, but the loop is // usually run only once. return QUtf8::isValidUtf8(QByteArrayView(d_name, len)).isValidUtf8; }QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters, QDirIterator::IteratorFlags flags) : nativePath(entry.nativeFilePath()) , dir(nullptr) , dirEntry(nullptr) , lastError(0) { Q_UNUSED(filters); Q_UNUSED(nameFilters); Q_UNUSED(flags); if ((dir = QT_OPENDIR(nativePath.constData())) == nullptr) { lastError = errno; } else { if (!nativePath.endsWith('/')) nativePath.append('/'); } }QFileSystemIterator::~QFileSystemIterator() { if (dir) QT_CLOSEDIR(dir); }bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) { if (!dir) return false; for (;;) { dirEntry = QT_READDIR(dir); if (dirEntry) { qsizetype len = strlen(dirEntry->d_name); if (checkNameDecodable(dirEntry->d_name, len)) { fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name, len), QFileSystemEntry::FromNativePath()); metaData.fillFromDirEnt(*dirEntry); return true; } } else { break; } } lastError = errno; return false; }QT_END_NAMESPACE#endif // QT_NO_FILESYSTEMITERATOR
the condition `checkNameDecodable(dirEntry->d_name, len)` has changed but the result is the same as in Qt 5.11
the reason to add this condition is a macOS bug: https://codereview.qt-project.org/c/qt/qtbase/+/265851, https://bugreports.qt.io/browse/QTBUG-76522, and i do not think it is a good way to limit the iteration in linux