2016-07-21 6 views
1

QFileをファイルリーダーとして使用し、ファイルライターを使用してアプリケーション内からファイルをUSBにコピーしています。私はUSBへのファイルコピー(プログレスバー付き)が長引く理由を理解しようとしています。私は最後に、書き込みに使用されるQFileオブジェクトを閉じると、close()操作が実際の書き込み操作に要した時間以上にかかることが分かりました。これらは非常に大きなファイルで、16384バイトのブロックを読み書きします。そして、ユーザーに表示されるプログレスバーを上げるためにGUIに信号を送ります。私は、実際にまだディスクに書き込まれていないアウトストリームの結果だと仮定しているので、各書き込みの後にflush()を呼び出すことを追加しました。それは違いはありませんでした。発信QFileオブジェクトのクローズは、書き込み時間(コピーの前後、およびQFile :: close()コールの前後で実行されたタイミングよりもずっと長い時間がかかりますが、タイミングコードは読書の容易さ、私はまたデバッグし、それが起こって見た)。もちろん、QFileオブジェクトの破壊によって呼び出されるため、close()関数を呼び出さないと助けになりません。次のようにQt5 QFile :: close()書き込みが非常に遅い

私のコードは、(マイナスエラーチェック、先のスペースのチェック、など)である:

void FileCopy::run() 
{ 
    QByteArray bytes; 
    int totalBytesWritten = 0; 
    int inListSize = inList.size(); 

    for (int i=0; !canceled && i<inListSize; i++) 
    { 
     QString inPath = inList.at(i).inPath; 
     QString outPath = inList.at(i).outPath; 
     QFile inFile(inPath); 
     QFile outFile(outPath); 
     int filesize = inFile.size(); 
     int bytesWritten = 0; 

     if (!inFile.open(QIODevice::ReadOnly)) 
     { 
      return; 
     } 

     if (!outFile.open(QIODevice::WriteOnly)) 
     { 
      inFile.close(); 
      return; 
     } 

     // copy the FCS file with progress 
     while (!canceled && bytesWritten < filesize) 
     { 
      bytes = inFile.read(MAXBYTES); 
      qint64 outsize = outFile.write(bytes); 
      outFile.flush(); 
      if (outsize != bytes.size()) 
      { 
       break; 
      } 
      bytesWritten += outsize; 
      totalBytesWritten += outsize; 
      Q_EMIT signalBytesCopied(totalBytesWritten, i+1, inListSize); 
      QThread::usleep(100); // allow time for detecting a cancel 
     } 

     inFile.close(); 
     outFile.close(); 
    } 

    // Other error checking done here 
} 

誰もがこれを渡される方法を見ることができますか?実際には進行状況バーの移動速度が遅くなり、進行状況バーが実際に完了するのに要した時間の半分以下で100%読み上げるよりも、コピーの状態をより正確に表示する方が望ましいでしょう。

QSaveFile :: commit()も同じ問題を抱えていますが、実際のコピーループを終了するよりもコミットに時間がかかります。 QFileがQIoDeviceから派生したのと同じ機能を使用しているからです。

私は標準ストリームの使用に移行することを検討しましたが、このアプリケーションでファイル処理がどのように一貫して行われるようにしたいと考えています。 QFile :: close()がこれを閉じるまでに時間がかかるようであれば、可能です。または、標準ストリームに同じ問題がある可能性はありますか?

私はVS2010をWin7の32ビットボックスで、Qt5.1.1とQt 1.2.2 VSアドインを使って作業しています。ご意見ありがとうございます。

答えて

1

あなたが書いている間、OSはたぶん書き込みをメモリに(速く)キャッシュします。しかし、ファイルを閉じると、すべてのデータをディスクにフラッシュする必要があります(遅い - 実際にはと書かれていない場合は特に)。だから、ファイルを閉じると、OSが実際にすべてのデータをディスク(USB)に置くのを待たなければならず、となることがあります。

オペレーティングシステムがこのようなことをする理由は、もちろん書き込みを高速化することです - そして、何も起こっていないときにバックグラウンドでディスクにデータをフラッシュすることができます。実際のコストに気付く。なぜなら、何も起こっていない間に償却されるからである)。しかし、ただ書くだけですぐに閉じてしまったら、気づくことになります。 注:書き込み呼び出しが遅くなる代わりに、同じ実際の時間を過ごすことになります。

+0

私は疑いがありました。だから、ユーザーの視点から見ると、100%に達してから100%になるのではなく、同じ時間をもう一度待たなければならないのではなく、進捗バーが100%に達していることがわかります。コピーをする。この時点で私の質問は、なぜ、実際にディスクに戻す前にデータをフラッシュするまで、ブロックしないのですか?私がそれを行えるようにすることができれば、プログレスバーはコピーの状態をより正確にユーザーに示します。この文脈では、私は実際にコピー状態を報告する正確さに関心があります。 – bmahf

+0

私はflush()を呼び出すときに書き込みをディスクにフラッシュさせる方法がありませんか?ユーザーへのインターフェースは、進行状況ボックスがなぜそこに到達するのにかかった時間よりも長く100%座っているのか分からないという事実によって妨げられています。 – bmahf

+0

'sync'、' fsync'などで試してみることができます。私はWindowsの専門家ではないので、そこで何をすべきかわかりません。 –

関連する問題