Qt QFile::size() 总是返回 0

Posted

技术标签:

【中文标题】Qt QFile::size() 总是返回 0【英文标题】:Qt QFile::size() always returns 0 【发布时间】:2018-06-03 17:46:18 【问题描述】:

我正在编写一个应用程序,我多次调用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()即可。

【问题讨论】:

取文件大小你打开它 您是否考虑过该文件可能根本不存在 我在调用 size() 之前打开文件。是的,它存在(我调用了 exists() 方法)。 创建QFile,将大小存储在一个int中,然后打开它。由于某种原因,打开的文件报告大小为 0。并且 IO 流总是报告 0,即使是位置,这听起来像一个错误。 好的,我试试,但是为什么在其他地方运行呢? (就像我展示的那样)我只想检查文件是否为空。 【参考方案1】:

我假设您正在使用一些流媒体来编写您的文件。问题是流媒体缓冲数据,它不会立即写入文件(它通常会等到缓冲区达到一定大小再将其写入)。

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/***/blob/master/50669271-qt-qfilesize-always-returns-0/main.cpp

【讨论】:

好的,现在可以了,但是我对 bufor 释放存储数据时的大小感兴趣?我在哪里可以找到这样的信息? 刷新流后,文件包含所有写入的数据,所以只需使用QFile::size 我知道。我只是好奇必须存储多少数据才能发布,因为在我的代码的某些部分,QFile::size 可以正常工作。无论如何,谢谢! 哦,不好意思,没看懂你的问题:QTEXTSTREAM_BUFFERSIZE默认是16KB; check here【参考方案2】:

假设打开后已修改的打开文件的文件大小是正确的,这是不可移植的。即使你可以“让它工作”,它仍然是错误的做法。打开文件后,您可以检查它有多大,然后您自己的代码必须跟踪它是如何改变大小的。您当然可以修补 Qt 来为您执行此跟踪,但只有通过QFileDevice(即QFileQSaveFile)访问文件时它才能工作。

【讨论】:

【参考方案3】:

在我的情况下,问题在于标志。 QIODevice::readOnly 并不总是返回正确的大小(总是 0)。改成QIODevice::readOnly 解决了这个问题。

【讨论】:

看起来你的答案可能需要更多细节,你说换成同样的东西解决了问题?

以上是关于Qt QFile::size() 总是返回 0的主要内容,如果未能解决你的问题,请参考以下文章

QT query.exec() 总是返回 false

QT 使用QDomDocument::setContent()读XML文件总是返回false

即使进程终止,waitpid 总是返回 -1

QSqlDatabase open 更新后总是返回true

Qt在控制台应用程序中录制音频

Qt 在控制台应用程序中录制音频