Kevin
Kevin

Reputation: 43

Qt QFile / QTemporaryFile cannot read or write

I have no idea why, but i can´t get the simplest example of QTemporaryFile to run... My real intent is to write data from QAudioInput into a temporary file before it is processed later.

After trying several times I realized that neither .read(), .readLine(), .readAll() or .write() would have any effect... The error string is always "Unknown Error" and it neither works for QFile or QTemporaryFile.

#include <QCoreApplication>
#include <QTemporaryFile>
#include <QDebug>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QTemporaryFile tf;
    tf.open();
    tf.write("Test");
    QTextStream in(&tf);
    qDebug() << "Testprogramm";
    qDebug() << tf.isOpen();
    qDebug() << tf.errorString();
    qDebug() << in.readLine();
    qDebug() << tf.readAll();
    tf.close();
    return a.exec();
} 

The debug posts:

Testprogramm
true
"Unknown error"
""
""

Thank you in advance!

Upvotes: 3

Views: 1818

Answers (1)

You need to move the file pointer back to the beginning of the file. This has to be done on the file itself when there's no stream on the file, or using the stream when one exists. Also - QFile is a proper C++ class that manages the file resource. There's no need to manually close the file. QFile::~QFile does that job.

The following works just fine:

#include <QtCore>

int main() {
    auto line = QLatin1String("Test");
    QTemporaryFile tf;
    tf.open();
    Q_ASSERT(tf.isOpen());
    tf.write(line.data());
    tf.reset(); // or tf.seek(0)
    QTextStream in(&tf);
    Q_ASSERT(in.readLine() == line);
    in.seek(0); // not in.reset() nor tf.reset()!
    Q_ASSERT(in.readLine() == line);
}

The above also demonstrates the following techniques applicable to sscce-style code:

  1. Inclusion of entire Qt module(s). Remember that modules include their dependencies, i.e. #include <QtWidgets> is sufficient by itself.

  2. Absence of main() arguments where unnecessary.

  3. Absence of QCoreApplication instance where unnecessary. You will get clear runtime errors if you need the application instance but don't have one.

  4. Use of asserts to indicate conditions that are expected to be true - that way you don't need to look at the output to verify that it is correct.

  5. Use of QLatin1String over QStringLiteral where ASCII strings need to be compared to both C strings and QStrings. Implicit ASCII casts can be a source of bugs and are discouraged.

    QLatin1String is a constant (read-only) wrapper, designed to wrap C string literals - thus there's no need to make line additionally const, although in real projects you'd want to follow the project's style guide here.

Upvotes: 2

Related Questions