Télécharger des fichiers à partir de SFTP avec la bibliothèque SSH.NET

ssortingng host = @"ftphost"; ssortingng username = "user"; ssortingng password = "********"; ssortingng localFileName = System.IO.Path.GetFileName(@"localfilename"); ssortingng remoteDirectory = "/export/"; using (var sftp = new SftpClient(host, username, password)) { sftp.Connect(); var files = sftp.ListDirectory(remoteDirectory); foreach (var file in files) { if (!file.Name.StartsWith(".")) { ssortingng remoteFileName = file.Name; if (file.LastWriteTime.Date == DateTime.Today) Console.WriteLine(file.FullName); File.OpenWrite(localFileName); ssortingng sDir = @"localpath"; Stream file1 = File.OpenRead(remoteDirectory + file.Name); sftp.DownloadFile(remoteDirectory, file1); } } } 

J’utilise la bibliothèque SSH.NET ( Renci.SshNet ) pour travailler avec un serveur SFTP. Ce que je dois faire, c’est récupérer les fichiers d’un dossier spécifique sur le serveur SFTP en fonction de la date du jour. Copiez ensuite ces fichiers du serveur SFTP sur un lecteur local, un de mes serveurs.

Ci-dessus, le code que j’ai mais il ne fonctionne pas. Parfois, il est indiqué que le fichier n’existe pas mais que les fichiers que je téléchargerai ne seront pas sur mes serveurs locaux, mais je dois télécharger tous les fichiers téléchargés dans le dossier distant pour la journée.

Quelqu’un peut-il jeter un coup d’œil et voir ce qui ne va pas? Je crois que cela a quelque chose à voir avec la partie stream. J’ai beaucoup travaillé avec FTP, mis à part le téléchargement de fichiers. J’ai pris un code précédent et je pensais pouvoir inverser le processus, mais cela ne fonctionnait pas. Le code que j’ai utilisé est basé sur cet exemple .

Un code de travail simple pour télécharger un fichier avec la bibliothèque SSH.NET est:

 using (Stream fileStream = File.Create(@"C:\target\local\path\file.zip")) { sftp.DownloadFile("/source/remote/path/file.zip", fileStream); } 

Voir aussi Téléchargement d’un répertoire à l’aide de SSH.NET SFTP en C # .


Pour expliquer, pourquoi votre code ne fonctionne pas:

Le deuxième paramètre de SftpClient.DownloadFile est un stream pour écrire un contenu téléchargé.

Vous passez dans un stream de lecture au lieu d’un stream d’écriture. De plus, le chemin avec lequel vous ouvrez le stream de lecture est un chemin distant, ce qui ne peut pas fonctionner avec la classe File fonctionnant que sur des fichiers locaux.

File.OpenRead ligne File.OpenRead et utilisez à la place le résultat de l’appel précédent File.OpenWrite (que vous n’utilisez plus du tout):

 Stream file1 = File.OpenWrite(localFileName); sftp.DownloadFile(file.FullName, file1); 

Ou encore mieux, utilisez File.Create pour File.Create tout contenu précédent que le fichier local peut avoir.

Je ne suis pas sûr si votre localFileName est censé contenir le chemin complet, ou juste le nom du fichier. Vous devrez donc peut-être aussi append un chemin, si nécessaire (combinez localFileName avec sDir ?)

Bien que l’exemple fonctionne, ce n’est pas la bonne façon de gérer les stream …

Vous devez vous assurer de la fermeture des fichiers / stream avec la clause using . En outre, ajoutez try / catch pour gérer les erreurs d’E / S …

  public void DownloadAll() { ssortingng host = @"sftp.domain.com"; ssortingng username = "myusername"; ssortingng password = "mypassword"; ssortingng remoteDirectory = "/RemotePath/"; ssortingng localDirectory = @"C:\LocalDriveFolder\Downloaded\"; using (var sftp = new SftpClient(host, username, password)) { sftp.Connect(); var files = sftp.ListDirectory(remoteDirectory); foreach (var file in files) { ssortingng remoteFileName = file.Name; if ((!file.Name.StartsWith(".")) && ((file.LastWriteTime.Date == DateTime.Today)) using (Stream file1 = File.OpenWrite(localDirectory + remoteFileName)) { sftp.DownloadFile(remoteDirectory + remoteFileName, file1); } } } } 

Ma version du code de @Merak Marey. Je vérifie si des fichiers existent déjà et des répertoires de téléchargement différents pour les fichiers .txt et autres.

  static void DownloadAll() { ssortingng host = "xxx.xxx.xxx.xxx"; ssortingng username = "@@@"; ssortingng password = "123";ssortingng remoteDirectory = "/IN/"; ssortingng finalDir = ""; ssortingng localDirectory = @"C:\filesDN\"; ssortingng localDirectoryZip = @"C:\filesDN\ZIP\"; using (var sftp = new SftpClient(host, username, password)) { Console.WriteLine("Connecting to " + host + " as " + username); sftp.Connect(); Console.WriteLine("Connected!"); var files = sftp.ListDirectory(remoteDirectory); foreach (var file in files) { ssortingng remoteFileName = file.Name; if ((!file.Name.StartsWith(".")) && ((file.LastWriteTime.Date == DateTime.Today))) { if (!file.Name.Contains(".TXT")) { finalDir = localDirectoryZip; } else { finalDir = localDirectory; } if (File.Exists(finalDir + file.Name)) { Console.WriteLine("File " + file.Name + " Exists"); }else{ Console.WriteLine("Downloading file: " + file.Name); using (Stream file1 = File.OpenWrite(finalDir + remoteFileName)) { sftp.DownloadFile(remoteDirectory + remoteFileName, file1); } } } } Console.ReadLine(); } 

Sans message d’erreur spécifique, il est difficile de faire des suggestions spécifiques.

Cependant, j’utilisais le même exemple et obtenais une exception d’permissions sur File.OpenWrite – en utilisant la variable localFileName, car en utilisant Path.GetFile pointait sur un emplacement qui, de toute évidence, ne serait pas autorisé à ouvrir un fichier> C: \ ProgramFiles \ IIS (Express) \ nom_fichier.doc

J’ai constaté que l’utilisation de System.IO.Path.GetFileName n’est pas correcte. Utilisez plutôt System.IO.Path.GetFullPath, pointez sur votre fichier commençant par “C: \ …”.

Ouvrez également votre solution dans FileExplorer et accordez des permissions à asp.net pour le fichier ou tout dossier contenant le fichier. J’ai pu télécharger mon fichier à ce moment-là.