8
votes

Is there another way to convet QFile to File? Different than this:

QFile myFile("goforward.raw");
int FileDescriptor = myFile.handle();
FILE* fh = fdopen(FileDescriptor, "rb");
3
Why do you need this? Can't you simply use the QFile for file operations?Etienne de Martel
And what's not working with what you have there?Mat
Because I use this function: png_init_io(png_ptr, fh); where the second param is File *. Thanks And yes work with code there but I like to use the only library QFile.Jjreina
This code is the way to do it. So explain why it doesn't work.Joe
Qt also supports reading and writing PNG files directly from QFile, with QImage::load/save or QImageReader/QImageWriter (or just QPixmap if there is only one PNG image per file).alexisdm

3 Answers

13
votes

We had very strange problems with our application and finally traced it to the QFile/fdopen issue:

void foo(QString filename)
{
    QFile qf(filename);
    qf.open(QIODevice::ReadOnly);
    int fd = qf.handle();
    FILE* f = fdopen(fd, "rb");
    // do some stuff with f
    fclose(f); // !!! undefined behaviour !!!
}

The problem with this code is that fclose(f) is called before the QFile object is destroyed, which is the wrong order: QTBUG-20372

...so either destroy the QFile object before calling fclose() or duplicate the file descriptor returned by QFile::handle():

void foo(QString filename)
{
    QFile qf(filename);
    qf.open(QIODevice::ReadOnly);
    int fd = qf.handle();
    FILE* f = fdopen(dup(fd), "rb"); // !!! use dup()
    // do some stuff with f
    fclose(f); // correct
}

P.S.: Those strange problems with our app showed up only on very few systems by a 10 second delay between a return statement at the end of a function and the actual return from that function. It was really weird. So this is an example of an "undefined behaviour" manifested in the real world :o)

7
votes

I think you already know that you have the various open, read, etc. methods in QFile. That said, if the file is not opened, then the handle method returns an error.

QFile myFile("goforward.raw");
myFile.open(QIODevice::ReadOnly);
int fileHandle = myFile.handle();

After that, you might reopen it with:

FILE* fh = fdopen(fileHandle, "rb");
-1
votes

If you have the file name, why don't you simply use

QFile *file = fopen(filename.toLocal8Bit().data(), "rb");

?

Isn't it way simpler than creating the QFile, opening it, retrieving the handle, etc.?

And it is pretty bug-free...