2009-10-02 18 views
5

Mam witrynę, w której użytkownik może pobrać plik. Niektóre pliki są bardzo duże (największe to 323 MB). Kiedy testuję to, aby spróbować pobrać ten plik, otrzymuję wyjątek z pamięci. Jedyny znany mi sposób pobrania tego pliku znajduje się poniżej. Powodem, dla którego używam poniższego kodu jest to, że adres URL jest zakodowany i nie mogę pozwolić użytkownikowi na bezpośrednie połączenie z plikiem. Czy istnieje inny sposób na pobranie tego pliku bez konieczności odczytywania całości w tablicy bajtów?Lepszy sposób na pobranie pliku binarnego?

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

Zadam oczywiste pytanie: czy możesz odczytywać ustaloną porcję z BinaryReader w pętli, wypisując ją do Response.BinaryWrite? Nie widzę powodu, dla którego musisz przeczytać cały plik do pamięci jako jedną operację. – Joe

Odpowiedz

16

Zamiast

context.Response.BinaryWrite(bytes); 

użytku

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

Pozwoli to uniknąć czytania całego pliku do pamięci.

+1

dzięki Peter! to działało świetnie. –

3

Spróbuj czegoś takiego:

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(); 
      } 
     } 

Ważną rzeczą jest to, że stosowanie mniejszej bufor i przepłukać strumień zapisu, aby usunąć z pamięci.

W tej chwili trzymasz cały pobrany plik zarówno w BinaryReader, jak i BinaryWriter. Cięcie pobierania na mniejszy bufor zmniejsza to obciążenie pamięci.

Powiązane problemy