Por HPNeo, el 20 de Junio del 2009. Sin comentarios.
Hace ya varios meses que vengo usando una parte de mi hosting como file box, es decir, una carpeta donde alojar unos cuantos archivos, tan simple como eso.
Como quería evitar tener que abrir una pestaña en el navegador para subir los archivos mediante una página, o abrir FileZilla, decidí crear una pequeña aplicación de escritorio que me permita subir los archivos con unos cuantos clicks.
Primero se crea un proyecto en Visual Studio y en el formulario principal se agrega un botón, además de un control OpenFileDialog (en este caso llamado opfFile). Además se referencia el namespace System.Net para el objeto WebClient que se utilizará para subir el archivo.
Luego, en el evento Click del botón que se agregó al inicio, se agrega esta porción de código.
WebClient wc = new WebClient();
opfFile.ShowDialog();
string filename = opfFile.FileName;
if(filename != ""){
byte[] responseArray = wc.UploadFile("URL_DEL_UPLOADER", "POST", filename);
string status = Encoding.ASCII.GetString(responseArray);
switch(status){
case "Error moving uploaded file.":
MessageBox.Show("Error moving uploaded file", "Info", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case "Invalid file.":
MessageBox.Show("Invalid file", "Info", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case "File too large.":
MessageBox.Show("File too large", "Info", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
default:
Clipboard.SetText(status);
MessageBox.Show("File uploaded successfully", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
break;
}
}
Voy a explicar paso por paso lo que hace esta porción de código:
Se crea un objeto WebClient (llamado wc), que permitirá subir los archivos al servidor, a continuación se abre la ventana para elegir el archivo mediante el método ShowDialog del objeto opfFile, para luego guardar la ruta física del archivo elegido en una variable string llamada filename.
Luego, se verifica que la variable filename no esté vacía (en caso de no haber elegido ningún archivo, por ejemplo), y en ese caso se procede a subir el archivo mediante el método UploadFile del objeto wc, guardando la respuesta del servidor en un array de byte llamado responseArray. El método UploadFile contiene 3 parámetros:
Para tener un mayor control de lo que sucede al subir el archivo, he creado un script en PHP que maneja el archivo subido (el cual explico líneas más abajo) y devuelve una serie de expresiones de acuerdo a la situación de la subida. Para que la aplicación sepa en qué estado ha terminado el script se obtiene la cadena que el servidor devolvió mediante la instrucción Encoding.ASCII.GetString(responseArray), el cual se guarda en una variable string llamada status.
Por último se verifica la cadena regresada mediante un switch y varios casos, algo que no necesita mayor explicación. El caso por defecto es la ruta del archivo en el servidor, el cual se copia al portapapeles (esto último me permite tener la URL a la mano ni bien termine de subirse el archivo).
Como escribí párrafos arriba, un script en PHP es el encargado de manejar el archivo que se subió mediante el cliente de escritorio. De esta manera se pueden evitar que se suban archivos muy pesados o que puedan ser usados maliciosamente.
<?php
$file['name'] = $_FILES['file']['name'];
$file['size'] = $_FILES['file']['size'];
$file['tmp] = $_FILES['file']['tmp_name'];
$file['error'] = $_FILES['file']['error'];
$extension = explode('.', $file['name']);
$file['extension'] = $extension[count($extension)-1];
if($file['extension']!='exe')
if($file['size'] < 600000)
if(move_uploaded_file($file['tmp'], 'files/'.time().'.'.$file['extension']))
echo 'http://box.hpneo.com/files/'.time().'.'.$file['extension'];
else
echo 'Error moving uploaded file.';
else
echo 'File too large.';
else
echo 'Invalid file.';
?>
En este caso se procede a guardar en un array los datos del archivo subido, luego empieza el filtrado mediante condicionales if:
if($file['extension']!='exe') : Si la extensión del archivo no es .exe, es decir, es un programa. En este if se pueden agregar varias condiciones de acuerdo a los tipos de archivo que se quieren evitar guardar. if($file['size'] < 600000) : Si el archivo pesa menos de 600 Kb. Se puede aumentar o disminuir el límite de tamaño en bytes. if(move_uploaded_file($file['tmp'], 'files/'.time().'.'.$file['extension'])) : En caso de fallar al mover el archivo desde su ubicación temporal a la ubicación final. Cada condicional tiene su caso contrario, en el cual se muestra el mensaje de error (o la URL del archivo subido, en caso que el proceso haya sido completo con éxito) que será tomado por el cliente de escritorio, como se vió anteriormente.
Como dato adicional, se renombra el archivo subido con un id único que es el timestamp (al cambiar por cada milisegundo es diferente al archivo subido inmediatamente anterior) mediante la función time().
Definitivamente este mini proyecto es algo sencillo pero que cumple su función, y espero que les sirva de igual forma que a mí me sirvió.