Лучший способ скачать бинарный файл? - PullRequest
5 голосов
/ 03 октября 2009

У меня есть сайт, где пользователь может скачать файл. Некоторые файлы имеют очень большой размер (самый большой - 323 МБ). Когда я тестирую его, чтобы попытаться загрузить этот файл, я получаю исключение нехватки памяти. Единственный известный мне способ загрузки файла - ниже. Причина, по которой я использую приведенный ниже код, заключается в том, что URL-адрес закодирован, и я не могу позволить пользователю связываться напрямую с файлом. Есть ли другой способ загрузить этот файл, не считывая все это в байтовом массиве?

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

Ответы [ 2 ]

16 голосов
/ 03 октября 2009

вместо

context.Response.BinaryWrite(bytes);

использовать

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

Это позволит избежать чтения всего файла в память.

3 голосов
/ 03 октября 2009

Попробуйте что-то вроде этого:

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

Важно то, что вы используете меньший буфер и очищаете поток записи, чтобы очистить память.

Прямо сейчас вы храните весь загружаемый файл как в BinaryReader, так и в BinaryWriter. Разделение загрузки в меньший буфер уменьшает эту нагрузку на память.

...