2013-05-04 14 views
6

Ich lade eine EXE-Datei aus dem Internet mit Indy (idHTTP), und ich kann Memorystream oder Filestream verwenden, um es auf der Festplatte zu speichern, aber ich weiß wirklich nicht, ob es einen Unterschied zwischen ihnen gibt in der Ergebnisstruktur der Datei?). Ich konnte dafür noch keine Antwort finden.Delphi - MemoryStream oder FileStream

Wo, hier 2 einfache Funktionen zu simulieren, was ich tue:

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; 

Was Sie Experten denken, über die eine oder andere Art (Memory oder Filestream) mit? Gibt es einen Unterschied in der Struktur der EXE-Datei, wenn Sie den einen oder anderen Typ verwenden? Welcher Typ wird empfohlen?

Vielen Dank! Ein schönes Wochenende wünsche ich ihnen!

+4

Die 'TMemoryStream' wie intern verwendet' TFileStream 'zum Speichern in Datei (für die 'SaveToFile'-Methode), also ist die Antwort ziemlich einfach - benutze' TFileStream'. – TLama

+0

Ich könnte über 2 Gründe für die Verwendung von TMemoryStream anstelle von TFileStream nachdenken. Vermeiden Sie eine Bereinigung im Dateisystem im Falle einer Ausnahme und die Notwendigkeit einiger Manipulationen, bevor Sie sie in einer Datei speichern. – bummi

+6

Ihr mutwilliger Gebrauch von 'mit' macht mich erschrocken. Ich würde empfehlen, dass du damit aufhörst. –

Antwort

5

Es gibt keinen Unterschied zwischen TMemoryStream oder TFileStream vom Strom Sicht.

Sie sind beide Ströme und halten einen Strom von Bytes und sind beide von TStream abgeleitet.

Sie können Ihre Funktion wie diese

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; 

generali umzusetzen und nennen es mit einem TFileStream

var 
    LStream : TStream; 

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

oder TMemoryStream oder was auch immer Strominstanz Sie

+0

Das ist in der Tat, wie der Code neu gedacht werden sollte. Aber ich denke, es geht nicht so sehr um Code, sondern um Design. Sollte der Speicher-Stream oder Datei-Stream für diesen Zweck verwendet werden, scheint die Frage zu sein. –

+1

@DavidHeffernan "Ich lade eine ** EXE-Datei ** aus dem Internet ... Gibt es einen Unterschied in der Struktur der ** EXE-Datei **, wenn der eine oder andere Typ verwendet wird?" OP fragt sich, ob 'TMemoryStream' die Daten anders als' TFileStream' speichern würde: o) –

+0

Ich habe die Frage nicht so gelesen, ich nehme an, weil es bizarr erscheint, dass irgendjemand denken könnte, dass der Inhalt eines Streams geändert wird wenn Sie es auf Festplatte statt auf Speicher speichern. Das ist einfach komisch! –

1

In vielen Fällen wird es keinen Sinn machen, einen Zwischenspeicherstrom zwischen den Download und die Datei zu stellen. Sie brauchen nur Speicher zu verbrauchen, da Sie die gesamte Datei in den Speicher legen müssen, bevor Sie sie auf die Festplatte schreiben können. Durch die direkte Verwendung eines Dateistreams wird dieses Problem vermieden.

Die Hauptsituation, in der die Dateistromoption Probleme hat, ist, wenn Sie sichergehen möchten, dass Sie die gesamte Datei erfolgreich heruntergeladen haben, bevor Sie sie auf dem Datenträger speichern. Wenn Sie beispielsweise eine vorherige Version einer Datei überschreiben, möchten Sie sie möglicherweise herunterladen, eine Hash-Signatur prüfen und dann nur die ursprüngliche Datei überschreiben. In diesem Szenario müssen Sie die Datei vor dem Überschreiben an einen temporären Speicherort stellen. Sie können einen Speicherstream verwenden oder einen Dateistream mit einem temporären Dateinamen verwenden.

+0

Ja, ich erstelle ein Installationsprogramm, und möglicherweise aktualisiert der Benutzer die Dateien. Also denke ich, dass ich MemoryStream benutzen werde, weil Dateien nicht so groß sind (2 oder 3 MB). Vielen Dank! – Guybrush

+0

@Paruba Sie können weiterhin einen Dateistream verwenden, wenn Sie möchten. Verwenden Sie einfach einen temporären Dateinamen. Wenn Sie zufrieden sind die heruntergeladene Datei, löschen Sie die alte und benennen Sie die temporäre Datei. –

+9

Die Verwendung eines 'TFileStream' hat einen weiteren Vorteil - die Fähigkeit, einen unterbrochenen Download fortzusetzen, ohne von vorne anfangen zu müssen.Wenn der HTTP-Server Byte-Bereiche unterstützt, können Sie 'TIdHTTP' konfigurieren, um dem Server mitzuteilen, welcher Teil der entfernten Datei gesendet werden soll, und nicht die gesamte Datei. Für kleine Dateien ist dies nicht so wichtig, aber für größere Dateien kann es sogar die Möglichkeit geben, verschiedene Abschnitte derselben Datei mit mehreren Threads gleichzeitig herunterzuladen. –