Subir archivos grandes

La carga de archivos basada en WEB puede utilizar los protocolos FTP y HTTP. Aunque la transmisión FTP es estable, la seguridad es un problema grave. El servidor FTP lee la biblioteca del usuario para obtener permisos, lo que sigue siendo un inconveniente para los usuarios. Sólo queda HTTP. Hay tres formas en HTTP, PUT, WEBDAV y RFC1867. Los dos primeros métodos no son adecuados para cargar archivos grandes. Básicamente, todas las cargas web que utilizamos son cargas de archivos basados ​​en formularios en formato HTML según RFC1867.

RFC1867:

1. Formulario HTML

La especificación HTML existente define ocho valores posibles para el atributo TYPE del elemento INPUT, a saber: CHECKBOX, OCULTO, MAGE, CONTRASEÑA, RADIO, RESET, ENVIAR y TEXTO. Además, cuando el formulario está en modo POST, el formulario tiene un atributo ENCTYPE de "aplicación/x-www-form-URL codificado" de forma predeterminada.

El estándar RFC1867 realiza dos cambios en HTML:

(1) Agrega una opción de archivo al atributo de tipo del elemento de entrada.

(2)2) La etiqueta de entrada puede tener un atributo de aceptación, que puede especificar una lista de tipos de archivos o formatos de archivos que se pueden cargar.

Además, el estándar también define un nuevo tipo MIME: multipart/form-data, y maneja archivos con ENCTYPE=multipart/form-data y/o contiene

Por ejemplo, cuando el autor del formulario HTML desea que el usuario cargue uno o más archivos, puede escribir:

<FORM ENCTYPE=multipart/FORM-data ACTION=_URL_METHOD=POST>

Archivo a ser procesado:

& ltNOMBRE DE ENTRADA = archivo de usuario 1 TIPO = archivo>

& ltTIPO DE ENTRADA = ENVIAR VALOR = ENVIAR ARCHIVO>

</FORM>

Lo que hay que cambiar en el DTD HTML es agregar una opción para la entidad InputType. Además, recomendamos utilizar una lista de tipos de archivos separados por comas como atributo ACEPTAR de la etiqueta de entrada.

...(otros elementos)...

& lt! ENTIDAD % Tipo de entrada(Texto|Contraseña|Casilla de verificación|

Radio|Enviar|Restablecer|

Imagen|Ocultar|Archivo)>

& lt ! Entrada de elemento: 0 vacío>

<! ATTLIST entrada

TIPO %InputType texto

NOMBRE CDATA # IMPLÍCITO - requerido para todas las operaciones excepto confirmar y restablecer

Valor CDATA # implícito

SRC % URI #implied - para entrada de imagen -

marcado (seleccionado) #implied

Tamaño CDATA #implied - similar a los números,

pero separados por comas, no espacios

Número MAXLENGTH implícito

ALIGN(TOP|Middle|Bottom)#IMPLIED

Aceptar CDATA #lista de tipos de contenido implícito

& gt

...(otros elementos)...

2. Retraso en la transferencia de archivos

p>

En algunos casos, se recomienda que el servidor valida algunos elementos (como nombre de usuario, número de cuenta, etc.) antes de que los datos del formulario estén realmente listos para aceptar datos. Sin embargo, después de pensarlo un poco, decidimos que si el servidor hiciera esto, sería mejor tener una serie de formularios que envíen elementos de datos previamente validados al cliente como campos "ocultos", o organizar los formularios de manera que Aquellos elementos que requieren validación se muestran primero.

De esta manera, los servidores que necesitan realizar aplicaciones complejas pueden mantener el estado del procesamiento de transacciones por sí mismos, mientras que los servidores que necesitan aplicaciones simples pueden implementarlo de manera simple.

Es posible que el protocolo HTTP necesite conocer la longitud total del contenido en toda la transacción. Incluso si no se solicita explícitamente, los clientes HTTP deben proporcionar la longitud total de todos los archivos cargados para que un servidor ocupado pueda determinar si el contenido del archivo es demasiado grande para procesarse por completo, devolver un código de error y cerrar la conexión en lugar de esperar hasta que se completen todos los datos. ha sido aceptado. Algunas aplicaciones CGI existentes necesitan conocer la longitud total del contenido de todas las transacciones POST.

Si la etiqueta de entrada contiene el atributo MAXLENGTH, el cliente puede tratar el valor del atributo como el número máximo de bytes que el servidor puede aceptar para el archivo transferido. En este caso, el servidor puede preguntarle al cliente cuánto espacio hay disponible en el servidor para cargar el archivo antes de que comience la carga. Sin embargo, cabe señalar que esto es sólo una pista y que las necesidades reales del servidor pueden cambiar después de crear el formulario y antes de cargar el archivo.

En cualquier caso, cualquier servidor HTTP puede interrumpir la transferencia del archivo a mitad de la transferencia si el archivo que se acepta es demasiado grande.

3. Otras soluciones para transferir datos binarios

Algunas personas sugieren usar el nuevo tipo MIME agregado, como el paquete agregado/mixto o de codificación de transferencia de contenido, para describir la longitud de datos binarios indeterminados en lugar de dividirlos en partes. Si bien no nos oponemos a esto, requiere trabajo adicional de diseño y estandarización para que todo sea aceptable y comprensible. Por otro lado, el mecanismo de división en partes funciona bien, se puede implementar fácilmente tanto en el lado emisor del cliente como en el lado receptor del servidor y funciona tan eficientemente como otras formas integrales de manejar datos binarios.

Carga de RFC

1. Obtenga los datos cargados una vez y luego analícelos y procéselos.

Después de leer N fragmentos de código, descubrí que tanto los programas sin componentes como algunos componentes COM usan Request. Método BinaryRead. Obtenga los datos cargados inmediatamente y luego analícelos y procéselos. Por eso la carga de archivos grandes es muy lenta. IIS no dijo que incluso si se cargan cientos de millones de archivos, tomará un tiempo analizarlos y procesarlos.

2. Escribe en el disco duro mientras recibes archivos.

Aprendí sobre componentes comerciales extranjeros, entre los cuales los más populares son Power-Web, Aspupload, Active File, ABC Upload, ASP SmartUpload y SA-Fileup. Entre ellos, ASPUPLOAD y SA-FILE son excelentes. Afirman ser capaces de procesar archivos 2G (la versión SA-FILE EE ni siquiera tiene un límite de tamaño de archivo) y la eficiencia es muy buena. ¿Son los lenguajes de programación mucho menos eficientes? Después de verificar algunos datos, creo que todos operan directamente el flujo de archivos. Esto no está limitado por el tamaño del archivo. Pero las cosas de los extranjeros no son del todo perfectas. Después de que ASPUPLOAD procesa archivos grandes, el uso de memoria es asombroso. Alrededor de 1G es común. En cuanto a SA-FILE, aunque es bueno, es difícil de descifrar. Luego se encontraron dos. Componente de carga NET. Web.UpLoadModule y AspnetUpload también operan flujos de archivos. Pero la velocidad de carga y la utilización de la CPU no son tan buenas como las de los componentes comerciales extranjeros.

Hice una prueba y transferí un archivo 1G dentro de la LAN. La velocidad de carga promedio de ASPUPLOAD es de 4,4 M/s, el uso de CPU es de 10 a 15 M y el uso de memoria es de 700 M. Los archivos SA son similares. El AspnetUpload más rápido es de solo 1,5 M/s, el promedio es de 700 k/s y el uso de la CPU es de 15 a 39. El entorno de prueba es PIII800, 256 M de memoria y 100 M de LAN. Creo que la baja velocidad de AspnetUpload puede deberse a que se reciben archivos y se escriben en el disco duro al mismo tiempo. El precio del bajo uso de recursos es la reducción de la velocidad de transmisión. Pero tengo que admirar los programas extranjeros, el uso de la CPU es muy bajo.

Problemas de carga

Todos nos hemos encontrado con algunos problemas al cargar archivos de gran tamaño. Establecer un valor grande de maxRequestLength no resuelve exactamente el problema, ya que bloquea todo el archivo hasta que se carga en la memoria.

De hecho, si el archivo es muy grande, a menudo vemos que Internet Explorer muestra una página que no se puede mostrar: servidor no encontrado o un error de DNS, y parece que no hay forma de detectar este error. ¿Por qué? Debido a que se trata de un error del lado del cliente, Application_Error del lado del servidor no puede manejarlo.

La solución es utilizar un HttpWorkerRequest implícito para leer los datos de la tubería establecida en el bloque por IIS a través de sus métodos GetPreloadedEntityBody y ReadEntityBody. Chris Hynes nos proporciona una solución de este tipo (usando HttpModule), que no solo le permite cargar archivos grandes, sino que también muestra el progreso de la carga en tiempo real.

Dos. Componentes de red, león. Tanto Web.UpLoadModule como AspnetUpload utilizan este esquema.

Principios de la solución:

Utilice HttpHandler para implementar funciones similares a las extensiones ISAPI, procesar información solicitada y enviar respuestas.

Puntos clave del plan:

1. httpHandler o HttpModule

A. Leer y escribir datos en bloques

b. -time Realice un seguimiento del progreso de la carga y actualice la metainformación.

2. Utilice el HttpWorkerRequest implícito y sus métodos GetPreloadedEntityBody y ReadEntityBody para procesar la secuencia del archivo.

3. Personaliza el analizador MIME de varias partes.

Intercepta automáticamente los delimitadores MIME.

Escribe el archivo en trozos como un archivo temporal.

Actualiza los datos recibidos, errores y finalizaciones de la aplicación en tiempo real.

xt/javascript" src="../css/tongji.js">