Réaliser un système de téléchargement avec barre de progression
Date de publication : 03/03/2008
Par
Rodrigue Hunel (Rodrigue Online)
Suite à mes diverses recherches, je n'ai pas trouvé de tutoriels décrivant
la méthode à utiliser pour effectuer ce genre d'application. Par conséquent,
ce tutoriel aura pour but de vous présenter une des méthodes possibles
pour réaliser une application de téléchargement avec l'affichage de l'état
d'avancement avec une barre de progression.
I. Introduction
II. La classe WebClient
III. Création de l'interface
IV. Moteur de l'application
IV-A. Sélection de l'emplacement de sauvegarde
IV-B. Utilisation du WebClient
IV-B-1. Tâches à effectuer au clic sur le bouton Télécharger
IV-B-2. Tâches à effectuer pendant le téléchargement
IV-B-3. Tâches à effectuer à la fin du téléchargement
IV-B-4. Tâches à effectuer suite à une demande d'annulation
IV-C. Améliorations
V. Code final
VI. Conclusion
VII. Remerciements
I. Introduction
Ce tutoriel aura pour but de vous présenter cette méthode qui est,
selon moi, la plus simple et qui utilise la classe
WebClient
de la
super classe System.Net.
II. La classe WebClient
WebClient est une classe qui offre des méthodes pour recevoir ou
envoyer des données depuis n'importe quelle ressource identifiable
par une adresse Internet (autrement dit sous la forme
http://site.domaine.fr/fichier/)
Dans le cas de ce tutoriel, nous nous limiterons qu'aux méthodes
de téléchargement :
-
OpenRead et OpenReadAsync : Permettent la
récupération de données depuis un flux Internet.
-
DownloadData et DownloadDataAsync : Téléchargent
les données et les renvoient sous forme de tableau d'octets.
-
DownloadFile et DownloadFileAsync : Téléchargent
des données pour les sauvegarder localement.
-
DownloadString et DownloadStringAsync : Téléchargent
et retournent une chaîne de caractères de type String.
-
CancelAsync : Permet l'annulation des téléchargements
en cours de traitement.
 |
Toutes les méthodes ayant pour suffixe Async sont exécutés
de la manière asynchrone. C'est-à-dire que ce sont des méthodes
non bloquantes et qu'elles permettent d'avoir des applications non
figées pendant le téléchargement des données.
|
III. Création de l'interface
L'interface, pour ce tutoriel, sera composée de divers composants
dont :
-
Deux boîtes de texte (textBox) :
-
La première servira à saisir l'adresse du fichier à
télécharger ;
-
La deuxième affichera l'adresse locale du fichier, choisie
par l'utilisateur, après le téléchargement.
-
Une boîte de dialogue (SaveDialogFile) qui permettra
de choisir l'emplacement et le nom de sauvegarde du fichier ;
-
Et trois boutons (button) :
-
Le premier permettra l'ouverture de la précédente boîte
de dialogue ;
-
Le second qui lancera le téléchargement suite à un clic ;
-
Et le dernier offrira la possibilité d'annuler le
téléchargement.
-
Une barre de progression qui affichera la progression du
téléchargement en temps réel.
Nous aurons donc l'interface suivante :
 |
Ici, j'ai rajouté deux propriétés, assez pratiques, au champ de
saisie qui servira à saisir l'adresse de téléchargement. Ces
propriétés sont :
|
- AutoCompleteMode à Suggest
- AutoCompleteSource à AllUrl
Elles permettront d'ajouter une auto-complétion, lors de la saisie,
qui permettra de récupérer une adresse déjà saisie dans votre
navigateur. Pour obtenir plus d'informations sur le sujet, n'hésitez
pas à consulter le tutoriel de Louis-Guillaume Morand :
L'auto-complétion dans une application .Net
IV. Moteur de l'application
Avant toutes choses, voici le fonctionnement de l'application qui
sera réalisé avec la classe WebClient :
-
On saisi l'adresse du fichier à télécharger ;
-
Ensuite on définit l'emplacement de sauvegarde sur le disque ;
-
Enfin, on lance le téléchargement suite à un clic sur le bouton
Télécharger. Au cours de ce téléchargement, la barre
de progression affichera son état d'avancement. Un clic sur
le bouton Annuler annulera le téléchargement et
supprimera le fichier temporaire;
-
Une fois le téléchargement terminé, nous aurons un fichier
enregistré localement et nous pourrons réitérer l'opération
si on le souhaite.
IV-A. Sélection de l'emplacement de sauvegarde
Comme je l'ai dit plus haut, nous avons une boîte de dialogue
qui nous permettra de le faire suite à un clic sur le bouton
Sélectionner (nommé ici : selectBouton). Par conséquent,
il nous reste plus qu'à définir l'action à effectuer suite à
ce fameux clic :
private void selectBouton_Click(object sender, EventArgs e)
{
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
saveTo.Text = saveFileDialog.FileName;
}
}
|
 |
saveTo est le nom du champ texte affichant l'emplacement de
sauvegarde choisi.
|
IV-B. Utilisation du WebClient
Au cours de ce paragraphe, nous allons définir les tâches à
effectuer suite au clic sur le bouton Télécharger,
pendant le téléchargement et à la fin du téléchargement.
Mais avant toute chose nous devons créer une instance vers
un objet de type WebClient. Pour ce faire, nous avons
deux options : soit le faire à partir de l'éditeur graphique
(comme cela a été fait pour la construction de l'interface),
soit en la déclarant nous même dans le code. Ici, j'opterais
pour la deuxième option.
 |
Si vous optez pour la deuxième option, n'oubliez pas d'inclure
la super-classe de WebClient et de définir l'instance de
manière globale afin de pourvoir l'utiliser dans n'importe
quelle fonction.
|
 |
Le téléchargement de fichier peut être une action bloquante,
il faut donc agir en conséquence soit en utilisant un Thread
ou encore un BackgroundWorker soit faire appel à la
méthode asynchrone disponible : DownloadFileAsync.
|
IV-B-1. Tâches à effectuer au clic sur le bouton Télécharger
Nous devons ici tout d'abord nous abonner à l'évènement
onclick du bouton Télécharger afin de
pouvoir définir toutes les tâches à effectuer. Pour information
ce bouton a pour nom : downloadBouton. On obtient
donc la fonction suivante.
private void downloadBouton_Click(object sender, EventArgs e)
{
WebClient client = new WebClient();
client.DownloadFileAsync(new Uri(fileToDownload.Text.Trim()), saveTo.Text);
downloadBouton.Enabled = false;
downloadBouton.Text = "En cours...";
cancelButton.Enabled = true;
}
|
IV-B-2. Tâches à effectuer pendant le téléchargement
On souhaite afficher uniquement l'état d'avancement, il
nous faut donc définir une fonction qui sera appelée à
chaque état d'avancement du téléchargement. Pour ce faire,
on doit abonner notre instance client à l'évènement
DownloadProgressChanged.
Tout d'abord, on définit notre nouvelle fonction
qui mettra à jour notre barre de progression.
private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
}
|
Puis on rajoute une nouvelle ligne à la fonction downloadBouton_Click :
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
|
 |
Avec les précédentes fonctions définies, nous avons déjà
une application qui permet d'effectuer un téléchargement
avec affichage de son état d'avancement. Il nous reste
plus qu'à rajouter les tâches à effectuer à la fin du
téléchargement.
|
IV-B-3. Tâches à effectuer à la fin du téléchargement
A la fin du téléchargement survient l'évènement DownloadFileCompleted
et c'est grâce à lui que l'on saura qu'il est terminé.
Tout d'abord, on définit les tâches à effectuer dans une
nouvelle fonction.
private void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
MessageBox.Show("Téléchargement terminé.");
fileToDownload.ResetText();
saveTo.ResetText();
saveFileDialog.Reset();
downloadBouton.Enabled = true;
downloadBouton.Text = "Télécharger";
cancelButton.Enabled = false;
progressBar.Value = 0;
}
|
Une fois que c'est fait, il nous reste plus qu'à lui dire
qu'il doit effectuer ces tâches suite à la capture de cet
évènement en s'y abonnant lors de la création de notre
instance (c'est-à-dire dans la fonction downloadBouton_Click).
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
|
Maintenant, il nous reste plus qu'à définir les actions
à effectuer dans le cas d'une demande d'annulation.
IV-B-4. Tâches à effectuer suite à une demande d'annulation
Ici, nous ferons appel à la méthode CancelAsync
qui, une fois appelée, mais fin au téléchargement. Donc
nous aurons une unique instruction dans notre fonction.
private void cancelButton_Click(object sender, EventArgs e)
{
client.CancelAsync();
}
|
Etant donné que le fait d'annuler le téléchargement émet
un évènement de fin de téléchargement (vu précédemment),
il faut modifier le code définit plus haut afin de
différencier l'annulation et un téléchargement terminé
avec succès.
On peut faire une modification de ce genre :
if (!e.Cancelled)
{
MessageBox.Show("Téléchargement terminé.");
}
else
{
MessageBox.Show("Téléchargement annulé.");
}
|
Une fois toutes ces étapes réalisées, nous avons enfin notre
logiciel de téléchargement qui est entièrement fonctionnel.
Toutefois, nous pouvons l'améliorer afin d'effectuer quelques
petites vérifications comme celle de la chaîne saisie par
l'utilisateur, par exemple.
IV-C. Améliorations
Comme je le disais plus haut, une des améliorations possibles
est la vérification de l'adresse saisie. Pour ce faire, il
existe des fonctions définies à cet effet.
Ainsi, on peut modifier la fonction.
private void downloadBouton_Click(object sender, EventArgs e)
{
if (Uri.IsWellFormedUriString(fileToDownload.Text.Trim(), UriKind.Absolute))
{
client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFileAsync(new Uri(fileToDownload.Text.Trim()), saveTo.Text);
downloadBouton.Enabled = false;
downloadBouton.Text = "En cours...";
cancelButton.Enabled = true;
}
else
{
MessageBox.Show("Vous devez saisir une adresse correcte");
}
}
|
V. Code final
WebClient client = null;
private void selectBouton_Click(object sender, EventArgs e)
{
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
saveTo.Text = saveFileDialog.FileName;
}
}
private void downloadBouton_Click(object sender, EventArgs e)
{
if (Uri.IsWellFormedUriString(fileToDownload.Text.Trim(), UriKind.Absolute))
{
client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
Uri url = new Uri(fileToDownload.Text.Trim());
client.DownloadFileAsync(url, saveTo.Text);
downloadBouton.Enabled = false;
downloadBouton.Text = "En cours...";
cancelButton.Enabled = true;
}
else
{
MessageBox.Show("Vous devez saisir une adresse correcte");
}
}
private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
}
private void reinitialisation()
{
fileToDownload.ResetText();
saveTo.ResetText();
saveFileDialog.Reset();
downloadBouton.Enabled = true;
downloadBouton.Text = "Télécharger";
cancelButton.Enabled = false;
progressBar.Value = 0;
}
private void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (!e.Cancelled)
{
MessageBox.Show("Téléchargement terminé.");
}
else
{
MessageBox.Show("Téléchargement annulé.");
}
reinitialisation();
}
private void cancelButton_Click(object sender, EventArgs e)
{
client.CancelAsync();
}
|
Voici quelques captures d'écran de l'application effectuant un
téléchargement.

Après sélection du fichier et de l'emplacement de sauvegarde

En cours de téléchargement

A la fin du téléchargement
 |
Je vous propose de télécharger le code source afin de pouvoir
l'utiliser sans avoir à le retaper :
|
VI. Conclusion
Ce tutoriel nous a permis de découvrir l'une des méthodes de
téléchargement de fichier et d'afficher son état d'avancement. Ce
n'est pas une méthode universelle mais elle a le mérite d'être
simple à mettre en oeuvre.
VII. Remerciements
Tous mes remerciements à
Cardi et
Aspic
pour leurs précieux conseils, ainsi qu'à
ArHacKnIdE
pour sa relecture.


Les sources présentées sur cette page sont libres de droits,
et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright ©
03/03/2008 Rodrigue Hunel. Aucune reproduction,
même partielle, ne peut être faite de ce site et de l'ensemble de son contenu :
textes, documents, images, etc sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E
de dommages et intérêts.
Cette page est déposée à la
SACD.