<input>
マルチパート フォーム データをポストする標準の HTML コントロールを使用して、大きなファイルを ASP.NET サーバーにアップロードしています。これは ASP.NET MVC アプリケーションです。
MSDN によると、HttpPostedFile
クラスはすぐにディスクにバッファリングされます。
「ファイルは MIME multipart/form-data 形式でアップロードされます。デフォルトでは、フォーム フィールドやアップロードされたファイルを含む、256 KB を超えるすべてのリクエストは、サーバー メモリに保持されるのではなく、ディスクにバッファリングされます。」
これは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);
}
私の web.config の httpRuntime ブロックは次のようになります。
<httpRuntime
executionTimeout="1200"
requestLengthDiskThreshold="2097151"
maxRequestLength="2097151"
useFullyQualifiedRedirectUrl="false"
minFreeThreads="8"
minLocalRequestFreeThreads="4"
appRequestQueueLimit="100" />
私の実装は機能し、ペイロード全体をバッファリングするために必要な同じ量のメモリがサーバーによって消費されることを除いて、複数のファイルが期待どおりにアップロードされます。InputStream がすべてをバッファリングしていると想定する必要があります。メモリの容量よりも多くのファイルをアップロードすると、予想どおりOutOfMemoryException
. これは、800 MB のファイルをアップロードするときのメモリ スパイクの画像です。
Flash/Silverlight ウィジェットを使用したり、カスタムを作成してアップロードをインターセプトして自分で処理したりできることはわかっていますが、 MSDN の言う通りにすれば (または私のやり方が間違っている場合) HttpModule
、現在の要件は問題なく機能します。HttpPostedFile