Qt QFile::size() 总是returns 0
Qt QFile::size() always returns 0
我正在编写一个应用程序,其中我多次调用 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;
}
我一直在寻找解决方案,但我已经尝试了所有这些方法来解决这个问题。
EDIT/SOLVED:
为了清楚起见,一切都围绕着 buffor,然而,在对文档稍作分析之后,我可以解释为什么只有这段代码没有 return QFile::size()
的正确值而不是所有(其中 none 个未达到缓冲区自动释放数据的大小)。在所有这些地方,都使用了 endl
,正如文档所说:Writes '\ n' to the stream and flush the stream. 所以现在一切都清楚了。在所有其他地方,调用了 flush()
方法,但我不知道。这么短的修正。
问题已解决,您需要做的就是调用 flush()。
我假设您正在使用一些流媒体来编写您的文件。问题是 streamer 缓冲数据,它不会立即写入文件(它通常等到缓冲区达到一定大小后再写入)。
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/Whosebug/blob/master/50669271-qt-qfilesize-always-returns-0/main.cpp
假设文件大小在打开后修改过的文件上是正确的是不可移植的。即使你可以 "get it to work",这仍然是错误的做法。打开文件后,您可以检查它有多大,然后您自己的代码必须跟踪它是如何改变大小的。您当然可以修补 Qt 来为您执行此跟踪,但只有通过 QFileDevice
(即 QFile
或 QSaveFile
)访问文件时它才会起作用。
在我的案例中,问题出在标志上。 QIODevice::readOnly
并不总是返回正确的大小(总是 0)。更改为 QIODevice::readOnly
解决了问题。
我正在编写一个应用程序,其中我多次调用 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;
}
我一直在寻找解决方案,但我已经尝试了所有这些方法来解决这个问题。
EDIT/SOLVED:
为了清楚起见,一切都围绕着 buffor,然而,在对文档稍作分析之后,我可以解释为什么只有这段代码没有 return QFile::size()
的正确值而不是所有(其中 none 个未达到缓冲区自动释放数据的大小)。在所有这些地方,都使用了 endl
,正如文档所说:Writes '\ n' to the stream and flush the stream. 所以现在一切都清楚了。在所有其他地方,调用了 flush()
方法,但我不知道。这么短的修正。
问题已解决,您需要做的就是调用 flush()。
我假设您正在使用一些流媒体来编写您的文件。问题是 streamer 缓冲数据,它不会立即写入文件(它通常等到缓冲区达到一定大小后再写入)。
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/Whosebug/blob/master/50669271-qt-qfilesize-always-returns-0/main.cpp
假设文件大小在打开后修改过的文件上是正确的是不可移植的。即使你可以 "get it to work",这仍然是错误的做法。打开文件后,您可以检查它有多大,然后您自己的代码必须跟踪它是如何改变大小的。您当然可以修补 Qt 来为您执行此跟踪,但只有通过 QFileDevice
(即 QFile
或 QSaveFile
)访问文件时它才会起作用。
在我的案例中,问题出在标志上。 QIODevice::readOnly
并不总是返回正确的大小(总是 0)。更改为 QIODevice::readOnly
解决了问题。