2009-10-02 14 views
5

Ich habe eine Website, wo ein Benutzer eine Datei herunterladen kann. Einige Dateien sind extrem groß (die größte ist 323 MB). Wenn ich es teste, um diese Datei herunterzuladen, erhalte ich eine Ausnahme wegen zu wenig Speicher. Der einzige Weg, wie ich die Datei herunterladen kann, ist unten. Der Grund, warum ich den folgenden Code verwende, ist, dass die URL codiert ist und ich den Benutzer nicht direkt mit der Datei verknüpfen lassen kann. Gibt es eine andere Möglichkeit, diese Datei herunterzuladen, ohne das Ganze in ein Byte-Array einlesen zu müssen?Besserer Weg, um eine Binärdatei herunterzuladen?

FileStream fs = new FileStream(context.Server.MapPath(url), FileMode.Open, 
                  FileAccess.Read); 
    BinaryReader br = new BinaryReader(fs); 
    long numBytes = new FileInfo(context.Server.MapPath(url)).Length; 
    byte[] bytes = br.ReadBytes((int) numBytes); 

    string filename = Path.GetFileName(url); 
    context.Response.Buffer = true; 
    context.Response.Charset = ""; 

    context.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
    context.Response.ContentType = "application/x-rar-compressed"; 
    context.Response.AddHeader("content-disposition", "attachment;filename=" + filename); 

    context.Response.BinaryWrite(bytes); 
    context.Response.Flush(); 
    context.Response.End(); 
+0

Ich werde die offensichtliche Frage stellen: Können Sie einen festen Chunk aus dem BinaryReader in einer Schleife lesen und in Response.BinaryWrite schreiben? Ich sehe keinen Grund, warum Sie die gesamte Datei als eine einzige Operation in den Speicher einlesen müssen. – Joe

Antwort

16

Statt

context.Response.BinaryWrite(bytes); 

Verwendung

context.Response.TransmitFile(context.Server.MapPath(url)); 

Diese die gesamte Datei in den Speicher einzulesen wird vermieden.

+1

danke Peter! das hat super geklappt. –

3

so etwas wie dieses Versuchen:

using (var br = new BinaryReader(fs)) 
     { 

      FileStream toFile = File.OpenWrite(ToFileName); 
      byte[] buff = new byte[2000]; 
      while (reader.Read(buff, 0, 2000) > 0) 
      { 
       toFile.Write(buff, 0, 2000); 
       toFile.Flush(); 
      } 
     } 

Das Wichtigste ist, dass Sie einen kleineren Puffer verwenden und die Write-Stream-Flash-Speicher zu löschen.

Im Moment halten Sie die gesamte Datei, die Sie herunterladen, in Ihrem BinaryReader und BinaryWriter. Das Chunking des Downloads in einen kleineren Puffer verringert diese Speicherbelastung.

Verwandte Themen