Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading entire file to QString

Tags:

file-io

qt

I'm trying to read all the files in a folder, store them in fileList via entryList() and then, for each file in that folder, open it and read its contents into a QString. I think this should be easy, but I can't figure out what I'm doing wrong. The error I'm getting now says:

no matching function for call to 'QTextStream::QTextStream(QFile*, QIODevice::OpenModeFlag)'

I understand that this relates to the wrong way I'm declaring the QTextStream, but the thing is that examples I found seem to DO this, so, why can't I?

Also, I noticed that if I add the test to check if the file open was successful, I get a warning saying "access denied", even if I'm just reading. Although, I can read the contents of the folder and even populate a QListWidget with those files with no problem.

The fact that these are *.JSON files should not matter, right?

I have seen this, this and this examples, but can't figure out what I'm doing wrong. Any help is appreciated.

This is my code:

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 With the modification suggested by cmannett85, I no longer get the error, but for some reason the string s is still empty in the end. Regarding the read/write permissions in the folder, I have now noticed that if I test

if(!file.open(QIODevice::ReadWrite))
        {
            QMessageBox::information(0,"error",file.errorString());
        }

I get two warnings - I'm suspecting provoked by . and .. - when I run the loop. Before it produced 32 warnings and I have 30 files inside the folder. Anyway, the files I'm trying to read are *.JSON and according to the properties dialog in Windows 7, they aren't set either as read-only or hidden. I can write files in the exact same folder with the same program.

There is one thing that I wonder if could be the reason for this: the filename contains . before the extension, ie, ID.file.16.json.

UPDATE 2 It is not related to the filename having . Tested it with different files and the result is the same.

Also,the two warnings were indeed related to the . and ... QDir::Filters solved the problem. Curiously, though, should I apply the QDir::Files filter, everything is ok; but if I use the QDir::NoDotAndDotDot filter, no files are detected whatsoever, contrary to the Qt Assistant explanation that says that only these two elements are ignored using this filter.

UPDATE 3

Followed ddriver's suggestion, but still isn't working. Current code, including the retrieval of of the files in the folder is:

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();

    }
like image 341
Joum Avatar asked Jun 17 '13 14:06

Joum


People also ask

How do you read a string in Qt?

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!!! }


4 Answers

As pointed out, there is no such constructor for QTextStream.

I quickly typed those few lines to verify it is indeed working properly:

foreach (QString file, files) {
    QFile f(file);
    if (!f.open(QFile::ReadOnly | QFile::Text)) break;
    QTextStream in(&f);
    qDebug() << f.size() << in.readAll();
}

And I do get the expected output - the size and content of each file. Try that code to check if you mistyped anything.

At this point I am pretty sure the problem is in your fileList - you don't check if QFile::open() succeeds and continue. Ironically, if open() fails and your code continues, you will get exactly 0 for the file size, and exactly an empty string for the result of readAll(). So the problem lies with your file names. And next time check if open() succeeds - not doing so is a very bad practice.

Another possible candidate for your files failing to open is if they are open for writing by some other process. Reboot your system and run your code directly to make sure the file access is not locked.

If that doesn't help too, head over to the Qt project website to post the problem there, and if necessary - a bug report.

like image 74
dtech Avatar answered Oct 27 '22 22:10

dtech


None of the examples you provide are creating QTextStream the way you are. QTextStream::QTextStream(QFile*, QIODevice::OpenModeFlag) does not exist, use QTextStream s1(&file), you have already set the open mode in the QFile.

Also, I noticed that if I add the test to check if the file open was successful, I get a warning saying "access denied", even if I'm just reading. Although, I can read the contents of the folder and even populate a QListWidget with those files with no problem.

Just because you have access to the folder, does not mean you can read the file contents. If you have read access and they are plain text files, you should be able to open them in a text editor. Can you?

like image 45
cmannett85 Avatar answered Oct 27 '22 22:10

cmannett85


From your example will not work, because you get the list of the files (filename) not the file with the path;

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!!!
}
like image 33
pepito Avatar answered Oct 27 '22 23:10

pepito


Well after a really big headache, I figured out that a really basic and simple error was causing this - the application path.

On the last piece of code I added in the question section, I added:

assetsFolder.setCurrent("C:/Users/THB7OI/Desktop/app/qt-book/chap08/items");

before the foreach loop and everything's working now.

Although this ended up as the definite answer, obtained by the contributions of the people that replied first, this wasn't the original question I had, and for that reason I +1'd the other two answers I got because they specifically replied to what I asked initially.

Also, as ddriver's answer specifically targeted the fileList problem and got me thinking about the application path, I marked it as the correct answer.

like image 43
Joum Avatar answered Oct 27 '22 23:10

Joum