在Linux中使用QTextStream进行异常文件读取操作

时间:2012-05-31 01:18:35

标签: file qt stream seek file-read

我使用的是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 
....

这里有一些关于test.txt的信息

$du  -sh test.txt 
1.1M    test.txt

$wc -c test.txt 
1100011 test.txt

$du -S test.txt 
1076    test.txt

3 个答案:

答案 0 :(得分:1)

不知何故,你的搜索指针在某个地方失去了轨道。这可能是由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的数量不同步。因此,如果你调用pos(),那么不同步会反映在你的texstream对象中。

答案 1 :(得分:1)

这是a bug in QTextStream::pos,它阻止了pos()使用大于16KB的文件(我认为),它似乎是fixed介于Qt 4.7和4.8之间。

但无论如何,在该循环中使用QTextStream::pos()会极大地影响阅读速度,所以,你应该避免它。

答案 2 :(得分:0)

您尝试阅读的文件似乎存在问题。检查test.txt的文件编码。如果您看到读取的数据大小,您将看到文本读取异常,读数从20K变为50K到100K。

代码很好,对我有用。