Подтвердить что ты не робот

Потоковая загрузка больших файлов в ASP.NET

У меня есть приложение ASP.NET MVC со страницей, которая позволяет пользователям загружать файлы. Файлы будут составлять несколько сотен мегабайт.

Я использую FineUploader на стороне клиента, который будет использовать FileAPI/XHR, если браузер поддерживает его, в противном случае отпадет в iframe/form с enctype = "multipart whatever".

Итак, на стороне сервера мне нужно оценить Request.Files.Count > 1. Если true, это старая школьная загрузка, и я сохраняю файл как Request.Files[0].InputStream.CopyTo(myFileStream), иначе я делаю Request.InputStreawm.CopyTo(myFileStream).

Вот некоторые из написанного мной кода: https://github.com/ronnieoverby/file-uploader/blob/master/server/ASP.NET%20MVC%20C%23/FineUpload.cs

Все это работает отлично, но в моем тестировании я заметил, что ни действие контроллера ASP.NET MVC, ни HttpHandler не начнут обрабатываться до тех пор, пока весь файл не будет загружен, что плохо, если файл очень большой, потому что это означает занимая много оперативной памяти веб-сервера.

Я нашел это: Потоковая загрузка больших файлов в ASP.NET MVC, которая кажется многообещающей, но я действительно не знаю, где находится код в его приложение.

Итак, возникает вопрос: как выгружать загруженные файлы на диск, пока загрузка все еще происходит в ASP.NET?

Update

Я только что увидел ключевую деталь, которая раньше не погружалась. Из документа HttpPostedFile:

По умолчанию все запросы, включая поля формы и загруженные файлы, размером более 256 КБ буферизуются на диск, а не хранятся на сервере память.

Хорошо, это касается опасений, что использование ОЗУ в сети может всплывать во время большой загрузки. Но все еще проблема: после того, как файл полностью перенесен на веб-сервер, серверу придется потратить время на его перемещение в конечный пункт назначения. Если операция файловой системы является копией (гарантируется, если пункт назначения находится на другом физическом диске), тогда ответ задерживается без необходимости.

Честно говоря, я мог бы, вероятно, жить с этим, увеличивая время отклика для обработчика/действия загрузки. Но было бы неплохо передать байты непосредственно в пункт назначения.

4b9b3361

Ответ 1

Вы можете обрабатывать закачки полностью настраиваемым способом без буферизации, используя HttpRequest.GetBufferlessInputStream. В основном вы получаете доступ к необработанным входящим данным и можете делать все, что хотите.

Я только что создал небольшой образец, который сохраняет содержимое необработанного запроса в файл:

  • Создайте обработчик:

    public class UploadHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            using (var stream = context.Request.GetBufferlessInputStream())
            using (var fileStream = File.Create("c:\\tempfile.txt"))
            {
                stream.CopyTo(fileStream);
            }
        }
        public bool IsReusable { get {  return true; } }
    }
    
  • Зарегистрируйтесь в Web.config:

    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
        <handlers>
            <add name="UploadHandler" verb="POST"
                path="/upload"
                type="UploadHandler"
            resourceType="Unspecified"/>
        </handlers>
    </system.webServer>
    
  • Создайте страницу с формой:

<form action="/upload" method="post" enctype='multipart/form-data'>
     <input type="file" name="aa" id="aa"/>
     <input type="submit"/>
</form>

Ответ 2

Если загрузка и потоковая передача использует ценные ресурсы сервера, вы можете взглянуть на размещение своих медиафайлов в каком-то облаке. Возможно, с помощью ASP.NET для использования Rackspace, API-интерфейс Amazon Cloud позволяет пользователям загружать файлы непосредственно в сеть CDN, а затем обслуживать контент таким образом, я знаю, что это не отвечает на ваш вопрос, но многие люди будут или уже есть подумал, что я получу свои 2 цента. Многие люди, которые все еще не хотят использовать облако, поражают меня! как только вы идете CDN, вы никогда не вернетесь. Кроме того, с большинством CDN вам также будет предоставлен потоковый URL-адрес для вашего загрузочного контейнера, в котором он поддерживает множество разных типов фильмов, и его быстрое освещение не только для ваших пользователей, но и у вас никогда не будет медленных скоростей на вашем веб-сайте, как результат.