1

Linux プラットフォーム (Ubuntu) と QT4.7.4 を使用しています。

まず、vi を使用してテスト ファイル「test.txt」を作成し、その中に「1234567890」と 100000 行を書き込むだけで、

次に、以下のコードをコンパイルして実行し、監督して、無限ループに入ります。

それについてのアイデアはありますか?ありがとう!

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
4

3 に答える 3

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
           }

       }

これはうまくいくはずです。

そしてs: 0 : true : (final-chunk-data-size) : (size-of-your-test.txt-file)、qdebug 出力の最終行として表示されます。

問題は、ts.pos();QTextStreamline qDebug()<<"s:"<<ts.status()<<":"<<ts.atEnd()<<":"<<str.count()<<":"<<ts.pos(); がバッファリングされるため、pos() 関数が有効なデバイス位置を再構築するためにデバイスをシークする必要がある場合があります。[QFile と TextStream を組み合わせて使用​​すると、テキスト ストリームの内部位置がファイルの位置と同期していない場合、pos() 関数によって内部的に使用されるこのシーク関数がひどく間違っている可能性があります!!]

したがって、呼び出さずに使用しても問題ありませんts.pos()。手動で行う必要はありませんseek。それ以外の場合、ts.pos() を追加する場合は、手動でseek.

pos 出力のシーケンスを参照してください。すべての pos() 呼び出しで、常に (10240 + 前の位置) が前の位置の値に追加されます。つまり、以前の位置の量だけファイルの位置と同期していないため、すべての pos() 呼び出しで以前の位置の値の量だけジャンプします。そのため、pos() を呼び出すと、非同期が texstream オブジェクトに反映されます。

于 2012-05-31T04:11:06.223 に答える
1

これはのバグでQTextStream::pospos()、 16KB を超えるファイルを使用できませんでした (私が思うに)、 Qt 4.7 と 4.8 の間のどこかで修正されたようです。

とにかく、QTextStream::pos()そのループ内で使用すると読み取り速度にひどく影響するので、避けるべきです。

于 2012-05-31T09:55:51.370 に答える
0

読み取ろうとしているファイルに問題があるようです。test.txt のファイル エンコーディングを確認します。読み取ったデータのサイズを見ると、読み取られたテキストに異常が見られ、読み取りは 20K から 50K から 100K に移動します。

コードは問題なく、私のために働いています。

于 2012-05-31T05:48:42.213 に答える