mvc5 - Transmisión de archivos de gran tamaño en ASP.NET
mvc upload file ajax (2)
Puede manejar las cargas de forma totalmente personalizada sin almacenamiento en búfer usando el método HttpRequest.GetBufferlessInputStream
. Básicamente, está obteniendo acceso a los datos entrantes sin procesar y de forma gratuita para hacer lo que quiera con ellos.
Acabo de crear una pequeña muestra que guarda el contenido de la solicitud en bruto en un archivo:
Crear manejador:
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; } } }
Registrarse en Web.config:
<system.webServer> <modules runAllManagedModulesForAllRequests="true"/> <handlers> <add name="UploadHandler" verb="POST" path="/upload" type="UploadHandler" resourceType="Unspecified"/> </handlers> </system.webServer>
Crea una página con un formulario:
<form action="/upload" method="post" enctype=''multipart/form-data''> <input type="file" name="aa" id="aa"/> <input type="submit"/> </form>
Tengo una aplicación MVC de ASP.NET con una página que permite a los usuarios cargar archivos. Los archivos serán de varios cientos de megabytes.
Estoy usando FineUploader en el lado del cliente, el cual usará FileAPI / XHR si el navegador lo admite, de lo contrario, volveré a Iframe / form con enctype = "multipart any".
Así que en el lado del servidor necesito evaluar Request.Files.Count > 1
. Si es true
, esta es una carga de la vieja escuela y Request.Files[0].InputStream.CopyTo(myFileStream)
el archivo como Request.Files[0].InputStream.CopyTo(myFileStream)
contrario hago Request.InputStreawm.CopyTo(myFileStream)
.
Aquí hay algo del código real que he escrito que hace esto: https://github.com/ronnieoverby/file-uploader/blob/master/server/ASP.NET%20MVC%20C%23/FineUpload.cs
Todo esto funciona bien, pero en mis pruebas he notado que ni una acción del controlador MVC de ASP.NET ni un HttpHandler comenzarán a procesarse hasta que se cargue el archivo completo, lo cual es malo si el archivo es muy grande porque eso significa que está ocupando mucho de la memoria RAM del servidor web.
Encontré esto: Transmisión de archivos de gran tamaño a ASP.NET MVC, que suena prometedor, pero realmente no tengo idea de dónde reside el código en su aplicación.
Entonces, la pregunta es: ¿cómo transmitir los archivos cargados al disco mientras la carga todavía se está realizando en ASP.NET?
Actualizar
Acabo de ver un detalle clave que no se había reflejado antes. De la documentación de HttpPostedFile :
De forma predeterminada, todas las solicitudes, incluidos los campos de formulario y los archivos cargados, de más de 256 KB, se almacenan en el búfer, en lugar de mantenerse en la memoria del servidor.
Ok, eso responde a la preocupación de que la utilización de RAM del servidor web podría aumentar durante una carga grande. Pero, todavía hay un problema: después de que el archivo se transfiere completamente al servidor web, el servidor tiene que dedicar tiempo a moverlo a su destino final. Si la operación del sistema de archivos es una copia (garantizada si el destino está en otro disco físico), la respuesta se retrasa innecesariamente.
Honestamente, probablemente podría vivir con esto aumentando el tiempo de espera de respuesta para el controlador / acción de carga. Pero, sería bueno transmitir los bytes directamente a su destino.
Si la carga y la transmisión están utilizando recursos valiosos del servidor, es posible que desee ver cómo alojar sus archivos multimedia en una nube de algún tipo. Es posible con ASP.NET usar un Rackspace, la API de Amazon Cloud hace que sus usuarios carguen los archivos directamente a una red CDN y luego sirvan el contenido de esa manera. Sé que esto no responde a su pregunta, pero muchas personas ya lo harán o ya lo han hecho. pensé que obtendría mis 2 centavos. ¡Muchas personas que aún no optan por usar la nube me sorprenden! Una vez que vas a CDN nunca vuelves. Además, con la mayoría de las CDN, también recibirá una URL de transmisión para su contenedor de carga donde admite muchos tipos diferentes de películas, y su iluminación es rápida, no solo para que los usuarios puedan subirlas, sino también para que nunca tenga velocidades lentas en su sitio web. resultado.