0

I need to open files with QFile and QString for multilingual without hair pulling. But I also need to manage the data of those files through the std::stream API. As many suggest, I used std::fstream stdFile(fdopen(qtFile.handle(), mode)); to do so.

However I hit a problem when it recurring operations. After a specific amount of file handling, the application crashes.

The following code can reproduce the crash:

int fileOperationCount = 0;
while (true)
{
    QFile qtFile("plop.txt");
    qtFile.open(QIODevice::ReadOnly);
    std::ifstream file = std::ifstream(fdopen(qtFile.handle(), "rb"));

    if (!file.good())
        throw std::exception();
    file.seekg(0, file.beg);
    if (!file.good())
        throw std::exception(); //Will ALWAYS trigger at fileOperationCount = 509

    qtFile.close();

    fileOperationCount++;
}

The 509th will crash after the seekg. It also happens if I were to manipulate hundreds of different files. It will still crash the 509th time I try to read a file, any file.

Any idea what I'm doing wrong ?

Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
agrum
  • 407
  • 2
  • 16
  • 1
    1. From the example code, I cannot really see why you would need QFile. Maybe only use fdopen and drop QFile altogether? 2. fdopen requied an [fclose](http://linux.die.net/man/3/fclose) – Robert Aug 21 '15 at 23:31
  • 1
    Why using QFile at all? Also, I think QFile is not happy to have its underlying fd moved or closed under his nose. – peppe Aug 22 '15 at 19:17
  • `QFile` is definitely not happy about it. I was using `QFile` because the encoding of the filename wasn''t correct when feeding a `std::fstream` with a `std::string`. So I converted it to a `QString` and fed it to a `QFile`. I now dropped the `QFile` and simply feed the `std::fstream` with a `std::wstring`, converting the `std::string` to a `std::wstring` using Qt still. – agrum Aug 23 '15 at 20:28

1 Answers1

1
   int fileOperationCount = 0;
    while (true)
    {
        std::ifstream file ("plop.txt",std::ios::in);

        if (!file.good())
            throw std::exception();
        file.seekg(0, file.beg);
        if (!file.good())
            throw std::exception();

        file.close();
        fileOperationCount++;
    }

this version works if the file exists, if it doesn`t file.good() is false due to eof (I think). If you want to use Qt for translation you can use

            std::ifstream file (QObject::tr("plop.txt"),std::ios::in);

or if the function is inside a QObject use just tr("..") for better context.

MarcinG
  • 840
  • 6
  • 21
  • `fclose(pFile);` crashes in this case. I have the same feeling as you considering the limit of handles. It just drives me crazy how I can't close them. – agrum Aug 21 '15 at 23:45
  • Sorry for editing my whole answers and posting not working one – MarcinG Aug 22 '15 at 00:36
  • I think it has to exists due to ifstream being input file so it kind of doesn`t make sense if it doesn`t exist – MarcinG Aug 22 '15 at 00:42
  • Following Robert's comment I looked how to avoid using `QFile`. I learned that `fstream` has a special constructor on Windows that takes `wchar*` as a file name. So my concern for multilingual support disappeared. Instead of using `QFile(QString::fromStdString(str))` I use `ifstream(QString::toStdWString(QString::fromStdString(str)).c_str())`. Thanks to the two of you. – agrum Aug 23 '15 at 20:21