UFO ET IT

ASP.NET MVC로 대용량 파일 업로드 스트리밍

ufoet 2020. 12. 9. 20:58
반응형

ASP.NET MVC로 대용량 파일 업로드 스트리밍


내가 작업중인 애플리케이션의 경우 사용자가 웹 사이트를 통해 매우 큰 파일 (예 : 수 기가 바이트)을 업로드 할 수 있도록 허용해야합니다. 불행히도 ASP.NET MVC는 서비스를 시작하기 전에 전체 요청을 RAM에로드하는 것처럼 보입니다. 특히 다음과 같은 코드를 통해 문제를 우회하려고합니다.

if (request.Method == "POST")
{
    request.ContentLength = clientRequest.InputStream.Length;
    var rgbBody = new byte[32768];

    using (var requestStream = request.GetRequestStream())
    {
        int cbRead;
        while ((cbRead = clientRequest.InputStream.Read(rgbBody, 0, rgbBody.Length)) > 0)
        {
            fileStream.Write(rgbBody, 0, cbRead);
        }
    }
}

RAM으로의 버퍼 요청 방식을 우회하지 못합니다. 이 문제를 쉽게 해결할 수있는 방법이 있습니까?


내 초기 코드가 기본적으로 정확하다는 것이 밝혀졌습니다. 필요한 유일한 변경은 변경하는 것입니다

request.ContentLength = clientRequest.InputStream.Length;

...에

request.ContentLength = clientRequest.ContentLength;

콘텐츠 길이를 결정하기 위해 전체 요청에서 전자 스트림; 후자는 단순히 Content-Length헤더를 확인하기 만하면 헤더가 모두 전송되어야합니다. 이를 통해 IIS는 요청을 거의 즉시 스트리밍 할 수 있으므로 원래 문제가 완전히 제거됩니다.


물론 가능합니다. HttpWebRequest 및 IHttpHandler를 사용한 RESTful 파일 업로드를 참조하십시오 . 저는이 방법을 몇 년 동안 사용해 왔으며 최소한 몇 기가 바이트의 파일로 테스트 된 사이트를 가지고 있습니다. 기본적으로 사용자는 생각보다 쉬운 고유 한 IHttpHandler를 만들고 싶습니다.

간단히 말해 IHttpHandler 인터페이스를 구현하는 클래스를 만듭니다. 즉, IsReusable 속성과 ProcessRequest 메서드를 지원해야합니다. 그 외에도 web.config에 사소한 변경 사항이 있으며 매력처럼 작동합니다. 요청 수명주기의이 단계에서는 업로드되는 전체 파일이 메모리에로드되지 않으므로 메모리 부족 문제를 깔끔하게 해결합니다.

web.config에서

<httpHandlers>
 <add verb="*" path="DocumentUploadService.upl" validate="false" type="TestUploadService.FileUploadHandler, TestUploadService"/>
</httpHandlers>

참조 된 파일 인 DocumentUploadService.upl이 실제로 존재하지 않습니다. 표준 핸들러가 요청을 가로 채지 않도록 대체 확장을 제공하기위한 것입니다. 파일 업로드 양식을 해당 경로로 지정하면 FileUploadHandler 클래스가 시작되어 실제로 파일을받습니다.

업데이트 : 사실 제가 사용하는 코드는 그 기사와 다르며 작동하는 이유를 우연히 발견 한 것 같습니다. 저는 HttpPostedFile 클래스를 사용합니다 . 여기서 "파일은 MIME multipart / form-data 형식으로 업로드됩니다. 기본적으로 256KB보다 큰 양식 필드 및 업로드 된 파일을 포함한 모든 요청은 서버 메모리에 저장되지 않고 디스크에 버퍼링됩니다. "

if (context.Request.Files.Count > 0)
{
    string tempFile = context.Request.PhysicalApplicationPath;
    for(int i = 0; i < context.Request.Files.Count; i++)
    {
        HttpPostedFile uploadFile = context.Request.Files[i];
        if (uploadFile.ContentLength > 0)
        {
            uploadFile.SaveAs(string.Format("{0}{1}{2}",
              tempFile,"Upload\\", uploadFile.FileName));
        }
    }
}

참고 URL : https://stackoverflow.com/questions/1046230/streaming-large-file-uploads-to-asp-net-mvc

반응형