我正在使用Linux平台(Ubuntu)和QT4.7.4,
首先,我使用 vi 创建一个测试文件"test.txt",只需在其中写入 100000 行"1234567890",
然后我编译并运行下面的代码,在我的监督下,它进入无限循环,
有什么想法吗?谢谢!
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QString str;
QFile file("./test.txt");
if ( file.open(QIODevice::ReadOnly | QIODevice::Text) ) {
QTextStream ts( &file );
while(!ts.atEnd()) {
str = ts.read(10240);
qDebug()<<"s:"<<ts.status()<<":"<<ts.atEnd()<<":"<<str.count()<<":"<<ts.pos();
}
}
return app.exec();
}
下面是 qdebug 输出:
s: 0 : false : 10240 : 10240
s: 0 : false : 10240 : 20480
s: 0 : false : 10240 : 51200
s: 0 : false : 10240 : 112640
s: 0 : false : 10240 : 235520
s: 0 : false : 10240 : 481280
s: 0 : false : 10240 : 972800
s: 0 : false : 10240 : -1
s: 0 : false : 10240 : -1
s: 0 : false : 10240 : -1
s: 0 : false : 10240 : -1
s: 0 : false : 10240 : -1
s: 0 : false : 10240 : -1
s: 0 : false : 10240 : -1
....
以下是有关测试的一些信息.txt
$du -sh test.txt
1.1M test.txt
$wc -c test.txt
1100011 test.txt
$du -S test.txt
1076 test.txt
QTextStream::pos
中的一个错误,它阻止对大于 16KB 的文件使用pos()
(我认为),它似乎已修复在 Qt 4.7 和 4.8 之间。
但无论如何,在该循环中使用QTextStream::pos()
会严重影响阅读速度,因此,您应该避免使用它。
不知何故,您的搜索指针在某处丢失了轨道。这可能是在内部调用由pos()
函数进行的查找函数中。
因此,请尝试在每次迭代中手动查找指针。我建议在迭代中读取小块数据。
试试这个
int pos=0;
QTextStream ts( &file );
while(!ts.atEnd()) {
pos+=5120;
{
str = ts.read(5120);
qDebug()<<"s:"<<ts.status()<<":"<<ts.atEnd()<<":"<<str.count()<<":"<<ts.pos();
ts.seek(pos);//manually seeking to current position
}
}
这应该有效。
您将在 qdebug 输出中看到s: 0 : true : (final-chunk-data-size) : (size-of-your-test.txt-file)
最后一行。
问题出在ts.pos();
line
qDebug()<<"s:"<<ts.status()<<":"<<ts.atEnd()<<":"<<str.count()<<":"<<ts.pos();
由于 QTextStream 是缓冲的,pos() 函数可能必须寻找设备来重建有效的设备位置。[有可能,如果你同时使用 QFile 和 TextStream,文本流的内部位置将与文件的位置不同步,这样 pos() 函数内部使用的这个搜索函数可能会出错!!
因此,如果您在不调用ts.pos()
的情况下使用它,它会正常进行。您不必手动seek
.否则,如果添加 ts.pos(),则应手动seek
。
查看 pos 输出的顺序,它总是在每次 pos() 调用中将(10240 + 上一个位置)添加到前一个位置值。 这意味着它在每次 pos() 调用中都会跳跃一定数量的先前位置值,因为它与文件的位置不同步。因此,如果您调用 pos(),则这种不同步会反映在您的 texstream 对象中。
您尝试读取的文件似乎存在一些问题。检查 test.txt 的文件编码。如果您看到读取的数据大小,您将看到读取的文本异常,读数从 20K 移动到 50K 再到 100K。
代码很好,对我有用。