2013-05-04 59 views
6

Indy(idHTTP)を使用してインターネットからEXEファイルをダウンロードしていますが、memorystreamまたはfilestreamを使用してディスクに保存できますが、実際には違いはありますかファイルの結果構造に?)。私はまだこの答えを見つけることができませんでした。私がやっているものをシミュレートするために、2つのシンプルな機能であるが、ここでDelphi - MemoryStreamまたはFileStream

あなたの専門家は、1つまたは他のタイプ(MemoryStreamをまたはファイルストリーム)を使用して、何を考え
Function DownloadMS(FUrl, Dest: String): Boolean; 
var 
    Http: TIdHTTP; 
    Strm: TMemoryStream; 
Begin 
    Result := False; 
    Http := TIdHTTP.Create; 
    Strm := TMemoryStream.Create; 
    With Http, Strm Do 
    Try 
    Try 
     Get(FUrl, Strm); 
     If (Size > 0) Then 
     Begin 
     Position := 0; 
     SaveToFile(Dest); 
     Result := True; 
     end; 
    Except 
    end; 
    Finally 
    Strm.Free; 
    Http.Free; 
    end; 
end; 

Function DownloadFS(FUrl, Dest: String): Boolean; 
var 
    Http: TIdHTTP; 
    Strm: TFileStream; 
Begin 
    Result := False; 
    Http := TIdHTTP.Create; 
    Strm := TFileStream.Create(Dest, fmCreate); 
    With Http, Strm Do 
    Try 
    Try 
     Get(FUrl, Strm); 
     Result := (Size > 0); 
    Except 
    end; 
    Finally 
    Strm.Free; 
    Http.Free; 
    end; 
end; 

? 1つまたは他のタイプを使用しているときにEXEファイルの構造に違いはありますか?どのようなタイプが推奨されますか?

ありがとうございました!良い週末を!

+4

'TMemoryStream'は'内部的に使用していますTFileStream'をファイルに保存する( 'SaveToFile'メソッド用)ので、答えはとても簡単です。' TFileStream'を使用してください。 – TLama

+0

TFileStreamの代わりにTMemoryStreamを使う理由は2つあります。例外が発生した場合のファイルシステムのクリーンアップを回避し、ファイルに保存する前にいくつかの操作を行う必要があります。 – bummi

+6

あなたの無慈悲な使い方は 'と'私を怖がらせる。私はそれをやめることをお勧めしたいと思います。 –

答えて

5

ストリームの観点からは、TMemoryStreamまたはTFileStreamの間に違いはありません。

これらは両方ともストリームであり、バイトストリームを保持し、両方ともTStreamから派生します。

あなたの関数は、この

function DownloadToStream(const AUrl : String; ADest : TStream): Boolean; 
var 
    LHttp: TIdHTTP; 
begin 
    LHttp := TIdHTTP.Create; 
    try 
    LHttp.Get(AUrl, ADest); 
    Result := ADest.Size > 0; 
    finally 
    LHttp.Free; 
    end; 
end; 

のように一般化実装とTFileStream

var 
    LStream : TStream; 

begin 
    LStream := TFileStream.Create('MyFile.exe', fmCreate); 
    if DownloadToStream('', LStream) then 
    ... 
end; 

またはTMemoryStreamまたは任意のストリームインスタンスでそれを呼び出すことができますあなたが好き

+0

それは実際にどのようにコードを再因子付けするべきかです。しかし、私はその質問がコードについてではなく、デザインについてだと思います。この目的のためにメモリストリームまたはファイルストリームを使用すべきかどうかは疑問です。 –

+1

@DavidHeffernan "インターネットから** EXEファイル**をダウンロードしています... ** EXEファイル**の構造に違いはありますか?もし 'TMemoryStream'が' TFileStream'とは違うデータを保存するのではないかと疑問に思っています:o) –

+0

このように質問を読まなかったのは、ストリームの内容が変わったと誰も思うことができないメモリではなくディスクに保存するときに使用します。それはちょっと変だ! –

1

多くの場合、ダウンロードとファイルの間に中間メモリストリームを置くことはありません。あなたがディスクに入れる前にファイル全体をメモリに置かなければならないので、メモリを消費するだけです。ファイルストリームを直接使用すると、その問題は回避されます。

ファイルストリームオプションに問題がある主な状況は、ディスクに保存する前にファイル全体を正常にダウンロードしたことを確認したい場合です。たとえば、以前のバージョンのファイルを上書きする場合は、ファイルをダウンロードし、ハッシュ署名を確認した後、元のファイルを上書きすることができます。このシナリオでは、上書きする前に一時的な場所にファイルを置く必要があります。メモリストリームを使用することもできますし、一時ファイル名を使用してファイルストリームを使用することもできます。

+0

はい、インストーラを作成していますが、ユーザーがファイルを更新している可能性があります。だから私はファイルが(2または3 MB)はあまり大きくないので、私はMemoryStreamを使用すると思います。ありがとうございました! – Guybrush

+0

@Paruba必要に応じてファイルストリームを使用することはできます。一時ファイル名を使用するだけです。ファイルがダウンロードできたらうれしいときは古いファイルを削除し、一時ファイルの名前を変更してください。 –

+9

'TFileStream'を使うことはもう一つの利点があります - 最初からやり直すことなく壊れたダウンロードを再開する能力。HTTPサーバーがバイト範囲をサポートしている場合、 'TIdHTTP'を設定して、ファイル全体ではなくリモートファイルのどの部分を送信するかを指定することができます。小さなファイルの場合、これはあまり重要ではありませんが、大きなファイルの場合は、同じファイルの異なるセクションを一度に複数のスレッドでダウンロードすることさえできます。 –