2013-05-04 93 views
6

我使用Indy(idHTTP)從互聯網下載EXE文件,我可以使用memorystream或filestream將其保存到磁盤,但我真的不知道它們之間是否有任何區別(也許在文件的結果結構中?)。我無法找到答案。Delphi - MemoryStream或FileStream

在哪裏,這裏有兩個簡單的函數來模擬我在做什麼:

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; 

你所專家考慮使用一種或另一種類型(MemoryStream的或FILESTREAM)?使用一種或其他類型時,EXE文件的結構是否有區別?推薦什麼類型?

謝謝!週末愉快!

+4

的'TMemoryStream'一個TFileStream

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

TMemoryStream或任何流實例調用它內部使用' TFileStream'用於保存到文件(對於SaveToFile方法),所以答案很簡單 - 使用'TFileStream'。 – TLama 2013-05-04 14:08:09

+0

我可以考慮使用TMemoryStream而不是TFileStream的兩個原因。在發生異常情況下避免在文件系統中進行清理,並且在將其保存到文件之前需要進行一些操作。 – bummi 2013-05-04 14:14:54

+6

你隨意使用'with'會讓我害怕。我建議你停止這樣做。 – 2013-05-04 14:20:49

回答

5

從流的角度來看,TMemoryStreamTFileStream沒有區別。

它們都是流,並保存一個字節流,都來自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; 

,並與你喜歡

+0

這確實是如何重新考慮代碼的。但我認爲這個問題不是關於代碼,而是關於設計。內存流或文件流應該用於這個目的似乎是一個問題。 – 2013-05-04 14:47:44

+1

@DavidHeffernan「我正在從互聯網上下載** EXE文件** ......使用一種或其他類型時,** EXE文件的結構有沒有什麼區別?」 OP在想「TMemoryStream」是否會存儲與「TFileStream」不同的數據:o) – 2013-05-04 15:12:56

+0

我沒有這樣讀過這個問題,我猜想,因爲看起來奇怪的是任何人都可以認爲流的內容被改變了當你將它存儲到磁盤而不是內存時。這太奇怪了! – 2013-05-04 15:16:25

1

在很多情況下,在下載和文件之間放入中間內存流是毫無意義的。所有這些都會消耗內存,因爲在將整個文件放入磁盤之前,必須將整個文件放入內存中。使用文件流直接避免了這個問題。

文件流選項出現問題的主要情況是,如果您想確保在保存到磁盤之前已成功下載了整個文件。例如,如果覆蓋文件的以前版本,則可能需要下載它,檢查散列簽名,然後才覆蓋原始文件。在這種情況下,您需要在覆蓋之前將文件放置在臨時位置。您可以使用內存流,也可以使用臨時文件名來使用文件流。

+0

是的,我正在創建一個安裝程序,也許用戶將更新文件。所以我想我會使用MemoryStream,因爲文件不是很大(2或3 MB)。謝謝! – Guybrush 2013-05-04 15:05:10

+0

@Paruba如果你願意,你仍然可以使用文件流。只需使用臨時文件名。當你喜歡下載的文件時,刪除舊的並重命名臨時文件。 – 2013-05-04 15:06:27

+9

使用'TFileStream'還有另外一個好處 - 能夠在不重新開始的情況下重新開始中斷下載。如果HTTP服務器支持字節範圍,則可以配置'TIdHTTP'來告訴服務器發送遠程文件的哪一部分,而不是整個文件。對於小文件,這並不重要,但對於較大的文件,它甚至可以同時使用多個線程下載同一文件的不同部分。 – 2013-05-04 17:57:44

相關問題