0

Indyとを使用してダウンロードマネージャーを開発していますDelphi XE(アプリケーションは使用しますMultithreadingサーバーへの複数の接続を試行します)。すべて正常に動作しますが、最終的にダウンロードされたファイルが壊れている場合があり、ダウンロードした一時ファイルを確認すると、そのうちの 2 つまたは 3 つが最後にゼロで埋められていることがわかります。(各一時ファイルは、各接続のダウンロード結果です)。ファイルが大きいほど、結果として壊れた一時ファイルが多くなります。たとえば、65,536,000 バイトの一時ファイルの 1 つでは、0 から 34,359,426 の範囲のみが有効で、34,359,427 から 64,535,999 まではゼロでいっぱいでした。これらのゼロを削除すると、アプリケーションは欠落しているセグメントを自動的にダウンロードし、結果として得られるものは、問題が再び発生しなければ、正常なダウンロード ファイルです。ダウンロード速度を落とさずに、一時ファイルの末尾にあるゼロを取り除きたいです。

PS私が使用していて、メソッドを使用してファイルをTFileStream直接送信し、ダウンロードしています。追加情報:パブリック変数に割り当てるイベントを処理します。ファイルがダウンロードされるたびに、ダウンロードされたファイルのサイズ (その変数) がテキスト ファイルに記録され、ログの内容から、ファイルが完全にダウンロードされたことがわかります (ゼロ バイトも含む)。TIdHTTPGETOnWorkAWorkCountint64Int64

4

1 に答える 1

1

ダウンロードする範囲を要求する前に、サーバーが実際にバイト範囲のダウンロードをサポートしていることを確認してください。サーバーが範囲をサポートしていない場合、要求された範囲はサーバーによって無視され、代わりにファイル全体が送信されます。まだ行っていない場合は、をTIdHTTP.Head()呼び出す前に、範囲サポートのテキストを使用する必要がありますTIdHTTP.Get()。また、最後にダウンロードしてからリモートファイルが変更されているかどうかを検出するには、これを行う必要があります。まともなダウンロードマネージャーは、そのようなことを処理できる必要があります。

また、転送されるバイト数が事前にわかっている場合は、データをダウンロードする前TIdHTTPに、宛先のサイズが事前に割り当てられることにも注意してください。TStreamこれは、を使用するときに転送を高速化し、ディスクI/Oを最適化するためTFileStreamです。したがって、ファイルの異なる領域に書き込んでいる場合でも、複数の同時ダウンロードの宛先と同じファイルにアクセスするために使用しないでください。TFileStream複数のオブジェクトを事前に割り当てるTFileStreamと、ファイルサイズを異なる位置に設定しようとして、互いに踏みにじられる可能性があります。複数のファイルを同時にダウンロードする必要がある場合は、次のいずれかを実行します。

1)必要なすべてのピースが揃ったら、各ピースを個別のファイルにダウンロードし、必要に応じて最終ファイルにコピーします。

2)カスタムTStreamクラスまたはIndyのTIdEventStreamクラスを使用して、ファイルI / Oを自分で管理します。これにより、TIdHTTPの事前割り当ての試行を無視し、複数のファイルI/O操作が互いに誤ってオーバーラップしないようにすることができます。

于 2012-08-27T23:44:26.037 に答える