Colabora
 

Descarga de Archivos utilizando Webclient

Complemento WebRequest y WebResponse

 

Fecha: 06/Dic/2011 (16-11-11)
Autor: Javier C

 


Introducción

En este ejemplo se utilizara las clase WebClient para realizar la descarga de archivos de la web, mientras que utilizaremos WebRequest y WebResponse para extraer la información de los archivos a descargar. Todas las clases son miembros de System.Net

Contenido:

  • Introduccion
  • Diseño
  • El Código
1)        Espacio de Nombres
2)        Codigo en el Form_Load
3)        Variables en el form
4)        Código en el Button
4.1)        Comprobar dirección
4.2)        Conexión a la web
4.3)        Lamar a las funciones
4.4)        SavefileDialog
4.5)        Averiguar el tamaño del archvo a descargar
4.6)        Iniciar la descarga
5)        Código en el Timer
5.1)        Averiguar el tamaño del archivo descargado
5.2)        Mostrar datos y progreso de descarga
6)        Funciones en el Módulo Funciones.vb
6.1)        Función para extraer la extencion del archivo
5.3)        Funcion para extraer el nombre y extencion del archivo

Introduccion:

Sobre el uso de la clase WebClient:

El proyecto se inició utilizando la clase Weclient, pero al momento de avanzar con el trabajo se encontraron serias dificultades. La primera se refiere a la consulta de datos a la web, se necesitaba una instrucción que consulte el tamaño de un archivo alojado en internet.  La única instrucción encontrada fue la siguiente:

Dim Tamaño_Archivo As Integer
Tamaño_Archivo= Webclient.DownloadData("www.ejemplo.com").Length

El problema de esta instrucción es que antes de devolver el tamaño del archivo, lo descarga al equipo local, entonces resultaría poco eficiente descargar un archivo 100mb solo para averiguar su tamaño. La búsqueda de otra solución me llevo a la utilización de las clases WebRequest y WebResponse, de las cuales solo encontré en ejemplos en c++  del siguiente articulo . De su análisis deducir los procedimientos de consulta, no así el procedimiento para la descarga.  Es así que el trabajo se desarrollo con tres clases cuando lógicamente podrían haberse utilizado dos.

Diseño:

El diseño está formado  por un Form, un TextBox (Text_URL), un Button (Bt_desc), un ProgessBar (ProgressBar1), y 3 Labels (Label1, Lab_Descarga y Lab_Porc), un Savefiledialog1, y un Timer1. Posee un modulo llamado Funciones, que posee todas las funciones utilizadas.

imagen

El código:

1) Espacio de Nombres

'Importamos los Espacios de Nombres Imports System.Net

2) Codigo en el Form_Load

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load  

Lab_Descarga.Hide()
Lab_Porc.Hide()
Me
.Text = "Gestor de descargas"

End Sub

3) Variables en el form:

'Las Variables     
Dim
L_archivo As Integer ' Tamño del archivo en la web
Dim
L_descarga As Integer = 0 ' Tamño del archivo local
Dim Ext_Archivo As String ' Extension del archivo
Dim
Nomb_Archivo_Temp As String ' Nombre del archivo (que podra ser temporal) extraido de la web
Dim Nomb_Archivo As String ' Nombre del archivo definitivo que se alojara localmente.

Aqui se declararon las variables a utilizar.


4) Código en el Button:


4.1) Comprobar dirección:

      ' Primero se debe comprobar que la dirección tenga el Http , Ftp etc..  sino va a dar una exepcion  

If
LCase(Mid(Text_URL.Text, 1, 7)) <> "http://" Then

' .. si no lo tiene lo agrega


Text_URL.Text = "http://" & Text_URL.Text

End If

Primero se comprueba que la dirección web del TextBox  este correctamente escrita, esto es porque en el siguiente código se realiza una comprobación donde devuelve error al escribir mal la direccion.


4.2) Conexión a la web

'Inicio WebRequest/WewResponse (Extraido del codigo de ejemplo         
'en C++ http://www.elguille.info/colabora/puntoNET/neo_mx_DescargaArchivos.htm)

Dim WRPeticion As WebRequest
Dim
WRRespuesta As WebResponse

Try


WRPeticion = WebRequest.Create _
(Text_URL.Text)

WRRespuesta = WRPeticion.GetResponse()

Catch ex As Exception

MessageBox.Show(ex.Message)

Exit Sub

End Try

Aqui utilizamos las clases WebRequest y WebResponse para conectarnos con la web ingresada en el textBox.


4.3) Lamar a las funciones:

        'Extraer extension del archivo         
Ext_Archivo = Extension(WRRespuesta.ContentType.ToString)

'Extraer nombre y extencion de archivo para colocar en el Saavefiledialog

Nomb_Archivo_Temp = Extraer(WRRespuesta.ResponseUri.ToString, "/")

Aquí extraemos la extencion del archivo a descargar y el nombre con su extension llamando a las funciones que se explican mas adelante.


4.4) SavefileDialog

'Abre el cuadro de dialogo para guardar el archivo         
SaveFileDialog1.InitialDirectory = My.Computer.FileSystem.SpecialDirectories.MyDocuments
SaveFileDialog1.Filter = "Archivos (*." & Ext_Archivo & ")|*." & Ext_Archivo & ""

'Si el nombre del archivo extraido de la web es ""

If
Nomb_Archivo_Temp = "" Then

'Salgo si cancelo

If SaveFileDialog1.ShowDialog = System.Windows.Forms.DialogResult.Cancel Then

Exit Sub

End If

'El nombre del archivo va a ser el que defina en el cuadro de dialogo

Nomb_Archivo = SaveFileDialog1.FileName

Else

'El nombre del archivo en el cuadro de dialogo va a ser igual al nombre del archivo en la web

SaveFileDialog1.FileName = Nomb_Archivo_Temp
'
El nombre del archivo va a ser igual al nombre en el cuadro de dialogo.

Nomb_Archivo = SaveFileDialog1.FileName

'Salgo si cancelo

If SaveFileDialog1.ShowDialog = System.Windows.Forms.DialogResult.Cancel Then

Exit Sub

End If

End If


4.5) Averiguar el tamaño del archvo a descargar

    'Averiguar el tamaño del archivo          
L_archivo = WRRespuesta.ContentLength


4.6) Iniciar la descarga

 'Inicio el timer          
Timer1.Interval = 1000
Timer1.Start()

'Inicio la descarga

Dim
Client As New WebClient()

Try

Client.DownloadFileAsync _
(New Uri(Text_URL.Text), _
Nomb_Archivo)

Catch ex As WebException
MessageBox.Show(ex.Message)

Exit Sub

End Try

While
Not ProgressBar1.Value = 100

Application.DoEvents()

End
While

ProgressBar1.Value = 0

Primero se inicia el Timer que controla el ProgressBar. Se utilizó la instrucción WebClient.DownloadFileAsync en vez de WebClient.DownloadFile, debido a que esta úlima bloqueaba los demas subprocesos, en este caso bloqueaba el Timer y por consiguiente todos los eventos de información descarga.

5) Código en el Timer


5.1) Averiguar el tamaño del archivo descargado

 'Averiguar el tamaño del archivo descargado    

If
FileSystem.Dir(Nomb_Archivo) Is Nothing Then

L_descarga = 0

Else

L_descarga = FileSystem.FileLen(Nomb_Archivo)

End If

La comprobación para determinar si el achivo fue alojado localmente, si no es asi L_decarga devolveria Null y posteriormente error.


5.2) Mostrar datos y progreso de descarga

'Definir el progreso de descarga          
ProgressBar1.Value = L_descarga / L_archivo * 100

'Convierto bytes a mbites

Dim Descarga As Decimal = FormatNumber(L_descarga / 1024 / 1024, 2)
Dim Archivo As Decimal = FormatNumber(L_archivo / 1024 / 1024, 2)

'Muestro los datos de descarga

Lab_Descarga.Show()
Lab_Porc.Show()
Lab_Descarga.Text = "Descargando " & Descarga & " mb de " & Archivo & " mb"
Lab_Porc.Text = ProgressBar1.Value & "%"

'Cuando termine la descarga

If ProgressBar1.Value = 100 Then
Timer1.Enabled = False
Lab_Descarga.Hide()
Lab_Porc.Hide()
MessageBox.Show("Descarga del archivo " & Nomb_Archivo & " finalizada")
End If

 En este código definen los valores del ProgressBar en porcentaje, luego se convierten los tamaños a Mbites para ser mostrados en los labels.


6) Funciones en el Módulo Funciones.vb


6.1) Función para extraer la extencion del archivo

'FUNCION PARA EXTRAER LA EXTENSION DEL ARCHIVO     
'Este codigo fue extraido de

'http://www.recursosvisualbasic.com.ar/htm/trucos-codigofuente-visual-basic/226-extraer-extension-de-path.htm
'y luego modificado a mis necesidades

'WRRespuesta.ContentType.ToString devuelve un String "Tipo/extension" o "Tipo/extension; Formato"


Function
Extension(ByVal Tpio_contenido As String) As String

Dim
cacteres_coma = InStr(Tpio_contenido, ";")
Dim cacteres_barra = InStr(Tpio_contenido, "/")
Dim Long_contenido = Len(Tpio_contenido)

If cacteres_coma = 0 Then
Extension = Mid(Tpio_contenido, cacteres_barra + 1, (Long_contenido - cacteres_barra))
Else
Extension = Mid(Tpio_contenido, cacteres_barra + 1, (Long_contenido - cacteres_barra) - (Long_contenido - cacteres_coma) - 1)
End
If
End
Function


5.3) Funcion para extraer el nombre y extencion del archivo

'FUNCION PARA EXTRAER EL NOMBRE DEL ARCHIVO     
'Este codigo fue extraido de
'http://www.recursosvisualbasic.com.ar/htm/trucos-codigofuente-visual-basic/226-extraer-extension-de-path.htm

'Con una pequeña medificacion


Function
Extraer(ByVal Path As String, ByVal Caracter As String) As String

If Caracter = "." And InStr(Path, Caracter) = 0 Then
'Esta es la modificacion: Si no se cumple la condicion devuelve ""

'Si la función 'Extraer' no devuelve un valor en todas

'las rutas de acceso de código. Podría darse una excepción

'de referencia nula en tiempo de ejecución cuando se utilice el resultado.

Extraer = ""
Exit
Function
End
If

Extraer = Right(Path, Len(Path) - InStrRev(Path, Caracter))

End Function

Nota:
A este proyecto le faltaria una función que permita salir del programa cuando se pierda la conexión a internet.


Espacios de nombres usados en el código de este artículo:

System.Net

 



Compromiso del autor del artículo con el sitio del Guille:

Lo comentado en este artículo está probado (y funciona) con la siguiente configuración:

El autor se compromete personalmente de que lo expuesto en este artículo es cierto y lo ha comprobado usando la configuración indicada anteriormente.

En cualquier caso, el Guille no se responsabiliza del contenido de este artículo.

Si encuentras alguna errata o fallo en algún link (enlace), por favor comunícalo usando este link:

Gracias.


Código de ejemplo (comprimido):

 

Fichero con el código de ejemplo: javierc_Descarga_de_Archivos_utilizando_Webclient.zip - 120 KB

(BE89D5892C5D389616A804816368ED2F: pega aquí el checksum del zip)

 


Ir al índice principal de el Guille