Я загружаю большие файлы на сервер ASP.NET, используя стандартный элемент управления HTML <input>
для публикации данных из нескольких частей. Это приложение ASP.NET MVC.
Согласно MSDN, класс HttpPostedFile
буферизует на диск из коробки:
"Файлы загружаются в MIME
формат multipart / form-data. От
по умолчанию все запросы, включая форму
поля и загруженные файлы, больше чем
256 КБ буферизуются на диск, а
чем хранится в памяти сервера. "
Я предполагаю, что это означает, что когда я получаю доступ к HttpPostedFileBase
в моем контроллере, то, когда я получаю доступ к свойству HttpPostedFileBase
InputStream
, я могу записать куда-нибудь файловый буфер, не беспокоясь о том, что сервер исчерпал память, которая, очевидно, является неработоспособным решением.
Вот немного псевдокода о том, как я обрабатываю каждый из входящих файлов из HttpPostedFileBase
.
for(var i = 0; i< Request.Files.Count;i++)
{
var fileBase = Request.Files[i];
if (fileBase.ContentLength == 0)
{
continue;
}
// One thread per file
ThreadPool.QueueUserWorkItem(state =>
{
// Read from fileBase.InputStream
},
null);
}
Блок httpRuntime моего web.config выглядит следующим образом:
<httpRuntime
executionTimeout="1200"
requestLengthDiskThreshold="2097151"
maxRequestLength="2097151"
useFullyQualifiedRedirectUrl="false"
minFreeThreads="8"
minLocalRequestFreeThreads="4"
appRequestQueueLimit="100" />
Моя реализация работает, несколько файлов загружаются, как и ожидалось, за исключением того, что сервер использует все тот же объем памяти, который требуется для буферизации всей полезной нагрузки. Я должен предположить, что InputStream буферизует все. Когда я загружаю больше файлов, чем у меня есть память, он предсказуемо падает с OutOfMemoryException
. Вот изображение всплеска памяти при загрузке файла 800 МБ.
Я знаю, что мог бы использовать виджет Flash / Silverlight или написать собственный HttpModule
, чтобы перехватывать загрузки и обрабатывать их самостоятельно, но текущее требование будет работать безупречно, если HttpPostedFile
сделает то, что MSDN говорит, что делает (или я делает это неправильно).