Qt QFile :: size () всегда возвращает 0 - PullRequest
0 голосов
/ 03 июня 2018

Я пишу приложение, в котором много раз вызываю метод QFile::size().Это работает во всех, кроме одного места.Я покажу это место и то, которое работает для сравнения.

, которое не работает:

while(!in.atEnd())
{
    if (fileOut.size() != 0) //This "if" isn't executed. (if I change != to == it always returns 0)
    {
      out<<endl;
      qDebug() << "Size of fileOut: " << fileOut.size(); 
    }

    QString temp;
    temp = in.readLine();
    out<<temp;
}

, которое работает:

if(fileOut.size() != 0) 
{
  out<<endl;
}

QString temp = in.readLine();
out<<temp<<endl;

temp = in.readLine();
out<<temp;

while(temp[temp.length()-1] != ']')
{
    temp = in.readLine();
    out<<temp;
}

Я искал решение, но я попробовал все эти способы, чтобы решить эту проблему.

РЕДАКТИРОВАТЬ / РЕШИТЬ: Ради ясности, всеТем не менее, после небольшого анализа документации я могу объяснить, почему только этот фрагмент кода не вернул правильное значение QFile::size(), а не все (ни один из них не достиг размера, в котором был бы буферосвободить данные автоматически).Во всех этих местах использовался endl, и, как сказано в документации: Записывает '\ n' в поток и сбрасывает поток. Так что теперь все ясно.Во всех других местах вызывался метод flush(), но я не знал об этом.Такая короткая коррекция.Проблема решена, все, что вам нужно сделать, это вызвать flush ().

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Невозможно предположить, что размер файла является правильным для открытых файлов, которые были изменены после открытия.Даже если вы можете «заставить его работать», это все равно неправильно.Открыв файл, вы можете проверить его размер, а затем ваш собственный код должен отслеживать, как он изменил размер.Конечно, вы можете установить исправление Qt для этого отслеживания, но оно будет работать только до тех пор, пока к файлу обращаются через QFileDevice (то есть QFile или QSaveFile).

0 голосов
/ 04 июня 2018

Я предполагаю, что вы используете какой-то стример для записи вашего файла.Проблема в том, что стример буферизует данные, они не записываются немедленно в файл (обычно он ожидает, пока буфер достигнет некоторого размера, чтобы записать его).

QFile::posможет и не отображать правильный размер, поскольку он не учитывает данные, которые все еще находятся в буфере, но не сбрасываются в файл.

Если вы flush(), у вас будет стримерправильный размер и положение курсора:

#include <qdebug.h>
#include <qfile.h>
#include <qtextstream.h>

int main(int argc, char* argv[])
{
  QFile f("example.txt");
  qDebug() << "f.size() before opening =" << f.size(); // correct

  if (!f.open(QFile::WriteOnly)) {
    qDebug() << "Error: not opened!";
    return 1;
  }    

  QTextStream out(&f);
  qDebug() << "f.size() before writing =" << f.size(); // 0: file was overwritten

  out << "Hello world!\n";
  qDebug() << "f.size() after writing =" << f.size(); // may be incorrect
  qDebug() << "f.pos() after writing =" << f.pos(); // may be incorrect

  out.flush();
  qDebug() << "f.size() after flushing =" << f.size(); // correct

  f.close();
  qDebug() << "f.size() after closing =" << f.size(); // correct

  return 0;
}

Следующий пример показывает еще худшую ситуацию, когда у вас может быть ненулевой размер, но он не соответствует правильному:

#include <qdebug.h>
#include <qfile.h>
#include <qtextstream.h>

int main(int argc, char* argv[])
{
  QFile f("example.txt");

  if (!f.open(QFile::WriteOnly)) return 1;

  QTextStream out(&f);

  for (int i = 0; i < 10000; ++i) { // 10000 works for me, may be you have to increase it to see the partial write
    out << "Hello world!\n";
  }
  qDebug() << "f.size() after writing =" << f.size(); // may be incorrect
  qDebug() << "f.pos() after writing =" << f.pos(); // may be incorrect

  out.flush();
  qDebug() << "f.size() after flushing =" << f.size(); // correct

  f.close();

  return 0;
}

Это связано с упомянутым выше фактом: в какой-то момент буфер был очищен, но некоторые данные еще предстоит записать.

Снова, чтобы быть уверенным, очистите поток перед проверкой размера.


ОБНОВЛЕНИЕ: код доступен на https://github.com/cbuchart/stackoverflow/blob/master/50669271-qt-qfilesize-always-returns-0/main.cpp

...