Я пытаюсь распечатать имена всех файлов в каталоге. Однако некоторые файлы не отображаются или не могут быть открыты.
Если я перезапущу программу, файлы, которые ранее не могли быть открыты, фактически открываются и отображаются.
Что здесь происходит?
Это мой код:
QDirIterator iterator(dir.absolutePath(), QDirIterator::Subdirectories);
while (iterator.hasNext()) {
iterator.next();QFile file(iterator.next());
if ( file.open( QIODevice::ReadOnly ) ) {
qDebug() << QFileInfo(file).fileName() << endl;} else {
qDebug() << "Can't open " << QFileInfo(file).fileName() << endl;
}
}
Здесь есть одна проблема:
iterator.next();
QFile file(iterator.next());
if ( file.open( QIODevice::ReadOnly ) ) {
Вы пытаетесь продвинуть итератор дважды внутри цикла. Это означает, что вы можете перебрать последний элемент, который будет представлять неверный файл, который затем потерпит неудачу по очевидным причинам.
В зависимости от содержимого папки, т. Е. От того, слегка ли она меняется при следующем запуске, т. Е. Добавляется или удаляется один файл, этот цикл может «работать» в следующий раз, т. Е. Будут открыты все файлы, которые он пытается открыть, но он все равно пропустил бы файлы в своей форме.
Правильным решением является удаление этой строки из итерации:
iterator.next();
Поэтому весь ваш код будет для вашего удобства:
QDirIterator iterator(dir.absolutePath(), QDirIterator::Subdirectories);
while (iterator.hasNext()) {
QFile file(iterator.next());
if ( file.open( QIODevice::ReadOnly ) )
qDebug() << "Opened:" << file.fileName() << endl;
else
qDebug() << "Can't open " << file.fileName() << file.errorString() << endl;
}
По крайней мере, две вещи, чтобы отметить в соответствии с комментариями:
Ты можешь использовать метод errorString () для получения дополнительной информации в таких случаях.
Вам не нужно создавать QFileInfo, чтобы получить имя файла. Объект QFile уже есть метод для этого.. Проблема в том, что вы выполняете итерацию рекурсивно, и поэтому вы печатаете только базовые имена, не зная, где находятся файлы. Вы также можете отображать одно и то же имя файла несколько раз, если в разных подкаталогах есть файлы с одинаковыми именами.
Почему вы не используете QDir :: entryList?
От Qt Assistant:
QStringList QDir :: entryList (const QStringList & nameFilters, Filters filters = NoFilter, SortFlags sort = NoSort) const
Возвращает список имен всех файлов и каталогов в каталоге, упорядоченный в соответствии с фильтрами имен и атрибутов, ранее установленных с помощью setNameFilters () и setFilter (), и отсортированными в соответствии с флагами, установленными с помощью setSorting ().
Фильтр имени, фильтр атрибута файла и спецификация сортировки могут быть переопределены с помощью nameFilters, фильтров и аргументов сортировки.
Возвращает пустой список, если каталог нечитаемый, не существует или если ничто не соответствует спецификации.
Смотрите также entryInfoList (), setNameFilters (), setSorting () и setFilter ().