Чтение всего файла в QString
Я пытаюсь прочитать все файлы в папке, сохранить их в fileList
через entryList()
, а затем для каждого файла в этой папке открыть его и прочитать его содержимое в QString
. Я думаю, что это должно быть легко, но я не могу понять, что я делаю неправильно. Ошибка, которую я получаю, теперь говорит:
no matching function for call to 'QTextStream::QTextStream(QFile*, QIODevice::OpenModeFlag)'
Я понимаю, что это связано с неправильным способом, я объявляю QTextStream
, но дело в том, что примеры, которые я нашел, похоже, делают это, поэтому почему я не могу?
Кроме того, я заметил, что если я добавлю тест, чтобы проверить, был ли файл открыт успешно, я получаю предупреждение, говорящее "доступ запрещен", даже если я просто читаю. Хотя, я могу прочитать содержимое папки и даже заполнить QListWidget
этими файлами без проблем.
Тот факт, что это файлы *.JSON, не имеет значения, верно?
Я видел этот, this и это примеры, но не могу понять, что я делаю неправильно. Любая помощь приветствуется.
Это мой код:
foreach(QString fileName, fileList){
QFile file(fileName);
file.open(QIODevice::ReadOnly);
QString s;
QTextStream s1(&file, QIODevice::ReadOnly);
s.append(s1.readAll());
qDebug() << "string content:" << s; // empty!!!
}
UPDATE
С модификацией, предложенной cmannett85, я больше не получаю ошибку, но по какой-то причине строка s
по-прежнему остается пустой.
Что касается прав на чтение и запись в папке, я заметил, что если я тестирую
if(!file.open(QIODevice::ReadWrite))
{
QMessageBox::information(0,"error",file.errorString());
}
Я получаю два предупреждения: я подозреваю, что вызвал .
и ..
- при запуске цикла. Перед этим было выпущено 32 предупреждения, и у меня есть 30 файлов внутри папки.
Во всяком случае, файлы, которые я пытаюсь прочитать, это *.JSON, и в соответствии с диалоговым окном свойств в Windows 7 они не установлены как в режиме "только для чтения", либо скрыты. Я могу писать файлы в одной и той же папке с той же программой.
Есть одна вещь, которую я задаюсь вопросом, может ли быть причиной этого: имя файла содержит .
перед расширением, т.е. ID.file.16.json
.
ОБНОВЛЕНИЕ 2
Это не связано с именем файла, имеющим .
Протестировано с разными файлами, и результат будет таким же.
Кроме того, оба предупреждения действительно были связаны с .
и ..
. QDir::Filters
решил проблему. Любопытно, однако, следует ли применять фильтр QDir::Files
, все в порядке; но если я использую фильтр QDir::NoDotAndDotDot
, файлы не обнаруживаются вообще, в отличие от объяснения Qt Assistant, в котором говорится, что только эти два элемента игнорируются с помощью этого фильтра.
ОБНОВЛЕНИЕ 3
Следующее предложение ddriver, но все еще не работает. Текущий код, включая извлечение файлов в папке:
QDir assetsFolder = QDir("C:/Users/THB7OI/Desktop/app/qt-book/chap08/items");
QStringList files = assetsFolder.entryList(QDir::Files);
// for each file in the folder,
foreach (QString file, files) {
QFile f(file);
if (!f.open(QFile::ReadOnly | QFile::Text)) break;
QTextStream in(&f);
qDebug() << f.size() << in.readAll();
f.close();
}
Ответы
Ответ 1
Как указывалось, такого конструктора для QTextStream
нет.
Я быстро набрал эти несколько строк, чтобы убедиться, что он действительно работает правильно:
foreach (QString file, files) {
QFile f(file);
if (!f.open(QFile::ReadOnly | QFile::Text)) break;
QTextStream in(&f);
qDebug() << f.size() << in.readAll();
}
И я получаю ожидаемый результат - размер и содержимое каждого файла. Попробуйте этот код, чтобы проверить, что вы что-то не поняли.
В этот момент я уверен, что проблема в вашем fileList
- вы не проверяете, завершено ли QFile::open()
и продолжается. По иронии судьбы, если open()
терпит неудачу и ваш код продолжается, вы получите ровно 0 для размера файла и ровно пустую строку для результата readAll()
. Поэтому проблема заключается в именах ваших файлов. И в следующий раз проверьте, удастся ли open()
- не делать это очень плохо.
Еще один возможный кандидат для ваших файлов, которые не открывается, - это если они открыты для записи каким-либо другим процессом. Перезагрузите свою систему и запустите свой код напрямую, чтобы убедиться, что доступ к файлам не заблокирован.
Если это тоже не помогает, перейдите на сайт проекта Qt, чтобы опубликовать там проблему, а при необходимости - отчет об ошибке.
Ответ 2
Ни один из приведенных вами примеров не создает QTextStream
так, как вы. QTextStream::QTextStream(QFile*, QIODevice::OpenModeFlag)
не существует, используйте QTextStream s1(&file)
, вы уже установили открытый режим в QFile
.
Кроме того, я заметил, что если я добавлю тест, чтобы проверить, открыт ли файл я получил предупреждение о том, что "доступ запрещен", даже если я просто чтение. Хотя, я могу прочитать содержимое папки и даже заполнять QListWidget с этими файлами без проблем.
Просто потому, что у вас есть доступ к папке, это не значит, что вы можете прочитать содержимое файла. Если у вас есть доступ на чтение, и они представляют собой текстовые файлы, вы можете открыть их в текстовом редакторе. Можете ли вы?
Ответ 3
Ну, после действительно большой головной боли, я понял, что эта простая и простая ошибка вызывала это - путь к приложению.
В последнем фрагменте кода, который я добавил в разделе вопросов, я добавил:
assetsFolder.setCurrent("C:/Users/THB7OI/Desktop/app/qt-book/chap08/items");
перед циклом foreach
и всем, что работает сейчас.
Несмотря на то, что это оказалось определенным ответом, полученным благодаря вкладу людей, которые ответили первыми, это был не тот первоначальный вопрос, который у меня был, и по этой причине я добавил два других ответа, которые я получил, потому что они специально ответил на то, что я спросил поначалу.
Кроме того, поскольку ответ ddriver специально нацелен на проблему fileList
и заставил меня задуматься о пути приложения, я отметил его как правильный ответ.
Ответ 4
Из вашего примера не будет работать, потому что вы получите список файлов (имя файла), а не файл с контуром;
QStringList filters;
filters << "*.json";
QDir assetsFolder = QDir("C:/Users/THB7OI/Desktop/app/qt-book/chap08/items");
assetsFolder.setNameFilters(filters);
assetsFolder.setFilter(QDir::Files);
QFileInfoList files = assetsFolder.entryInfoList();
foreach (QFileInfo fi, files) {
QFile file(fi.absoluteFilePath());
if (!f.open(QFile::ReadOnly | QFile::Text)) continue;
QTextStream in(&f);
qDebug() << "string content:" << in.readAll(); // will not be empty!!!
}