Subir archivos a un servidor por partes

viernes, 8 de enero de 2010
Si bien es posible subir un archivo desde una página web usando el control FileUpload muchas veces nos vemos en la necesidad de hacerlo desde otros entornos, para esto .Net Framework cuenta con algunos assemblies que nos permiten tanto subir un archivo como una unidad o por partes.
Para representar esta situación lo que vamos a hacer es un proyecto de tipo class library (assembly),este usara los namespaces System.IO, System.Net, será necesario agregarlos a la lista de namespaces.
En esta oportunidad haremos uso de la clase WebClient (Ssytem.Net.Webclient) esta clase es muy útil en este contexto, ya que nos abstrae de la complejidad que se presenta al hacer un PUT http con otras clases del framework.
El código siguiente presenta a una función que toma un stream (el archivo a subir) y lo copia al destino en pequeñas porciones "chunks" de datos.
Algunas salvedades con respecto al código:
El servidor que use para desarrollar el código es un IIS 6.0 en el cual tengo permisos para subir archivos, si la seguridad del IIS no es ajustada a las necesidades de la funcionalidad que estamos desarrollando los errores 405 y 401 (Acceso denegado y no autorizado respectivamente) se harán presentes.
Las excepciones que están siendo capturadas son solo algunas de las que se podrían presentar, capturas mas especializadas son recomendadas.

public void Upload(string fileName, Stream localStream, int chunkSize)
{
//Declaracion de variables a ser usadas
System.Net.WebClient Client = new System.Net.WebClient();
byte[] chunk = new byte[localStream.Length];
int offset = 0;
int byteRead = 0;
//Establecer el usuario que tiene permisos para subir archivos
Client.Credentials =new System.Net.NetworkCredential("MiUsuario",
"MiClave",
"MiDominio");
try
{
do
{
//Se verifica el tamaño del bytes a leer
//para no agregar bytes al archivo
if (localStream.Length - localStream.Position <>
chunkSize = (int)(localStream.Length - localStream.Position);
//se sube una porcion del archivo a memoria
byteRead = localStream.Read(chunk, offset, chunkSize);
//se sube la porcion leida del archivo al destino
Client.UploadData("http://localhost/test/" + fileName,
"PUT", chunk);
//marcamos la posicion de la ultima lectura
offset += byteRead;
} while (localStream.Position != localStream.Length);
}
catch (FileNotFoundException ex)
{ throw new Exception("File Not Found", ex); }
catch (TimeoutException ex)
{ throw new Exception("Timeout", ex); }
catch (Exception ex)
{ throw new Exception("Unknow error", ex); }
}

0 comments:

Publicar un comentario