Le téléchargement de tous les fichiers via FTP et C#
Quelle est la meilleure façon de télécharger tous les fichiers dans un répertoire distant à l'aide de C# et de FTP et de les enregistrer dans un répertoire local?
le téléchargement de tous les fichiers dans un dossier spécifique semble être une tâche facile. Cependant, il ya certaines questions qui doit être résolu. Pour n'en nommer que quelques-uns:
Comment obtenir la liste des fichiers (Système d'.Net.FtpWebRequest vous donne unparsed liste et liste de répertoire format n'est pas standard dans tous les RFC)
Que si le répertoire distant a la fois les fichiers et sous-répertoires. Devons-nous nous plonger dans les sous-dossiers et de télécharger du contenu?
Que si certains des fichiers à distance existent déjà sur l'ordinateur local? Devraient-ils être remplacés? Ignorés? Doit-on remplacer les anciens fichiers seulement?
Que si le fichier local n'est pas accessible en écriture? Si tout le transfert de l'échec? Doit-on ignorer le fichier et continuer à la prochaine?
Comment gérer les fichiers sur un disque distant qui sont illisibles car nous n'avons pas de droits d'accès suffisants?
Comment sont les les liens symboliques, des liens en dur et les points de jonction manipulés? Des liens peuvent facilement être utilisé pour créer un infini récursive structure d'arborescence de répertoires. Considérons Un dossier avec des sous-dossier B, qui en fait n'est pas le véritable dossier mais les *nix lien en dur pointant vers le dossier A. L'approche naïve prendra fin dans une application qui ne se termine jamais (du moins si personne ne parviens à retirer le bouchon).
Décent tiers composant FTP doit avoir une méthode pour le traitement de ces problèmes. De code suivant utilise notre Rebex FTP pour .NET.
using (Ftp client =newFtp()){//connect and login to the FTP site
client.Connect("mirror.aarnet.edu.au");
client.Login("anonymous","my@password");//download all files
client.GetFiles("/pub/fedora/linux/development/i386/os/EFI/*","c:\\temp\\download",FtpBatchTransferOptions.Recursive,FtpActionOnExistingFiles.OverwriteAll);
client.Disconnect();}
Le code est pris de mon article sur le blog disponible à blog.rebex.net. Le blog a également fait référence à un exemple qui montre comment demander à l'utilisateur la façon de traiter chaque problème (par exemple, Remplacer/Écraser les plus anciens/Sauter/Sauter tous).
Pour le protocole FTP, vous pouvez utiliser FtpWebRequest de la classe de .NET framework. Bien qu'il ne dispose d'aucun soutien explicite pour les opérations sur les fichiers (y compris les téléchargements). Vous devez mettre en œuvre la récursivité vous-même:
Liste le répertoire distant
Parcourir les entrées, le téléchargement de fichiers et recursing dans les sous-répertoires (liste de nouveau, etc.)
Partie difficile est d'identifier les fichiers de sous-répertoires. Il n'y a aucun moyen de le faire que de façon portable avec le FtpWebRequest. Le FtpWebRequest malheureusement ne prend pas en charge la MLSD de commande, qui est le seul portable moyen de récupérer le répertoire de la liste avec les attributs de fichier dans le protocole FTP. Voir aussi Vérifier si l'objet sur le serveur FTP de fichier ou de répertoire.
Vos options sont:
Faire une opération sur un nom de fichier qui est certain échec pour le fichier et réussit pour les répertoires (ou vice versa). I. e. vous pouvez essayer de télécharger le "nom". Si cela réussit, c'est un fichier, si cela échoue, c'est un répertoire. Mais qui peut devenir un problème de performance, lorsque vous avez un grand nombre d'entrées.
Vous pouvez être chanceux et dans votre cas particulier, vous pouvez dire à un fichier à partir d'un répertoire par un nom de fichier (c'est à dire tous vos fichiers ont une extension, alors que les sous-répertoires ne sont pas)
Vous utilisez une longue liste de répertoires (LIST commande = ListDirectoryDetails méthode) et essayer d'analyser un serveur spécifique de la liste. De nombreux serveurs FTP utiliser *nix-style de liste, où vous identifier un répertoire par la d au tout début de l'entrée. Mais le nombre de serveurs à utiliser un format différent. L'exemple suivant utilise cette approche (en supposant que les *nix format)
voidDownloadFtpDirectory(string url,NetworkCredential credentials,string localPath){FtpWebRequest listRequest =(FtpWebRequest)WebRequest.Create(url);
listRequest.UsePassive=true;
listRequest.Method=WebRequestMethods.Ftp.ListDirectoryDetails;
listRequest.Credentials= credentials;List<string> lines =newList<string>();
using (WebResponse listResponse = listRequest.GetResponse())
using (Stream listStream = listResponse.GetResponseStream())
using (StreamReader listReader =newStreamReader(listStream)){while(!listReader.EndOfStream){
lines.Add(listReader.ReadLine());}}foreach(string line in lines){string[] tokens =
line.Split(new[]{' '},9,StringSplitOptions.RemoveEmptyEntries);string name = tokens[8];string permissions = tokens[0];string localFilePath =Path.Combine(localPath, name);string fileUrl = url + name;if(permissions[0]=='d'){Directory.CreateDirectory(localFilePath);DownloadFtpDirectory(fileUrl +"/", credentials, localFilePath);}else{FtpWebRequest downloadRequest =(FtpWebRequest)WebRequest.Create(fileUrl);
downloadRequest.UsePassive=true;
downloadRequest.UseBinary=true;
downloadRequest.Method=WebRequestMethods.Ftp.DownloadFile;
downloadRequest.Credentials= credentials;
using (Stream ftpStream = downloadRequest.GetResponse().GetResponseStream())
using (Stream fileStream =File.Create(localFilePath)){
ftpStream.CopyTo(fileStream);}}}}
La url doit être comme:
ftp://example.com/ ou
ftp://example.com/path/
Ou utiliser la 3ème partie de la bibliothèque qui prend en charge récursive téléchargements.
En interne, WinSCP utilise le MLSD de commande, si la prise en charge par le serveur. Si pas, il utilise le LIST de commande et prend en charge des dizaines de liste des formats.
(Je suis l'auteur de WinSCP)
Juste au sujet de télécharger winSCP pour cet objectif précis, merci d'avance. A obtenu un sentiment que cela peut me sauver du temps.
le téléchargement de tous les fichiers dans un dossier spécifique semble être une tâche facile. Cependant, il ya certaines questions qui doit être résolu. Pour n'en nommer que quelques-uns:
Décent tiers composant FTP doit avoir une méthode pour le traitement de ces problèmes. De code suivant utilise notre Rebex FTP pour .NET.
Le code est pris de mon article sur le blog disponible à blog.rebex.net. Le blog a également fait référence à un exemple qui montre comment demander à l'utilisateur la façon de traiter chaque problème (par exemple, Remplacer/Écraser les plus anciens/Sauter/Sauter tous).
OriginalL'auteur Martin Vobr
À l'aide de C# FtpWebRequest et FtpWebReponse, vous pouvez utiliser la récursivité (assurez-vous que le dossier de chaînes se terminent en '\'):
Le "point.Contient du('.')" c'est un peu primitif, mais a travaillé pour mes fins. Poster un commentaire si vous avez besoin d'un exemple de méthodes:
ou
OriginalL'auteur Handprint
Pour le protocole FTP, vous pouvez utiliser
FtpWebRequest
de la classe de .NET framework. Bien qu'il ne dispose d'aucun soutien explicite pour les opérations sur les fichiers (y compris les téléchargements). Vous devez mettre en œuvre la récursivité vous-même:Partie difficile est d'identifier les fichiers de sous-répertoires. Il n'y a aucun moyen de le faire que de façon portable avec le
FtpWebRequest
. LeFtpWebRequest
malheureusement ne prend pas en charge laMLSD
de commande, qui est le seul portable moyen de récupérer le répertoire de la liste avec les attributs de fichier dans le protocole FTP. Voir aussi Vérifier si l'objet sur le serveur FTP de fichier ou de répertoire.Vos options sont:
LIST
commande =ListDirectoryDetails
méthode) et essayer d'analyser un serveur spécifique de la liste. De nombreux serveurs FTP utiliser *nix-style de liste, où vous identifier un répertoire par lad
au tout début de l'entrée. Mais le nombre de serveurs à utiliser un format différent. L'exemple suivant utilise cette approche (en supposant que les *nix format)La
url
doit être comme:ftp://example.com/
ouftp://example.com/path/
Ou utiliser la 3ème partie de la bibliothèque qui prend en charge récursive téléchargements.
Par exemple avec WinSCP .NET de l'assemblée vous pouvez télécharger tout le répertoire avec un seul appel à
Session.GetFiles
:En interne, WinSCP utilise le
MLSD
de commande, si la prise en charge par le serveur. Si pas, il utilise leLIST
de commande et prend en charge des dizaines de liste des formats.(Je suis l'auteur de WinSCP)
OriginalL'auteur Martin Prikryl
Vous pouvez utiliser
System.Net.WebClient.DownloadFile()
, qui prend en charge FTP. MSDN Détails iciOriginalL'auteur STW
Vous pouvez utiliser FTPClient de laedit.net. Il est sous licence Apache et facile à utiliser.
Il utiliser FtpWebRequest :
WebRequestMethods.Ftp.ListDirectoryDetails
pour obtenir le détail de l'ensemble de la liste du dossierWebRequestMethods.Ftp.DownloadFile
pour le télécharger vers un dossier localOriginalL'auteur Jérémie Bertrand