Télécharger un répertoire en utilisant SSH.NET SFTP en C#

j'utilise Renci.SSH et C# pour se connecter à mon serveur Unix à partir d'une machine Windows. Mon code fonctionne comme prévu lorsque le contenu du répertoire n'est que des fichiers, mais si le répertoire contient un dossier, je reçois ce

Renci.SshNet.Commun.SshException:' Failure '

C'est mon code, Comment puis-je le mettre à jour pour aussi télécharger un répertoire (s'il existe)

private static void DownloadFile(string arc, string username, string password)
{
    string fullpath;
    string fp;
    var options = new ProgressBarOptions
    {
        ProgressCharacter = '.',
        ProgressBarOnBottom = true
    };

    using (var sftp = new SftpClient(Host, username, password))
    {
        sftp.Connect();
        fp = RemoteDir + "/" + arc;
        if (sftp.Exists(fp))     
            fullpath = fp;
        else
            fullpath = SecondaryRemoteDir + d + "/" + arc;

        if (sftp.Exists(fullpath))
        {
            var files = sftp.ListDirectory(fullpath);
            foreach (var file in files)
            {
                if (file.Name.ToLower().Substring(0, 1) != ".")
                {
                    Console.WriteLine("Downloading file from the server...");
                    Console.WriteLine();
                    using (var pbar = new ProgressBar(100, "Downloading " + file.Name + "....", options))
                    {
                        SftpFileAttributes att = sftp.GetAttributes(fullpath + "/" + file.Name);
                        var fileSize = att.Size;
                        var ms = new MemoryStream();
                        IAsyncResult asyncr = sftp.BeginDownloadFile(fullpath + "/" + file.Name, ms);
                        SftpDownloadAsyncResult sftpAsyncr = (SftpDownloadAsyncResult)asyncr;
                        int lastpct = 0;
                        while (!sftpAsyncr.IsCompleted)
                        {
                            int pct = (int)((long)sftpAsyncr.DownloadedBytes / fileSize) * 100;
                            if (pct > lastpct)
                                for (int i = 1; i < pct - lastpct; i++)
                                    pbar.Tick();
                        }
                        sftp.EndDownloadFile(asyncr);
                        Console.WriteLine("Writing File to disk...");
                        Console.WriteLine();
                        string localFilePath = "C:" + file.Name;
                        var fs = new FileStream(localFilePath, FileMode.Create, FileAccess.Write);
                        ms.WriteTo(fs);
                        fs.Close();
                        ms.Close();
                    }
                }
            }
        }
        else
        {
            Console.WriteLine("The arc " + arc + " does not exist");
            Console.WriteLine();
            Console.WriteLine("Please press any key to close this window");
            Console.ReadKey();
        }
    }
}
1
demandé sur Martin Prikryl 2018-09-18 21:40:40

1 réponses

BeginDownloadFile Téléchargements un fichier . Vous ne pouvez pas l'utiliser pour télécharger un dossier. Pour cela vous devez télécharger les fichiers un par un.

l'exemple suivant utilise le téléchargement synchrone ( DownloadFile au lieu de BeginDownloadFile ) pour la simplicité. Après tout, vous êtes en attente synchrone de téléchargement asynchrone à compléter de toute façon. Pour mettre en œuvre une barre de progrès avec téléchargement synchrone, voir affichage de l'état du téléchargement de fichier dans une barre de progrès avec SSH.NET .

public static void DownloadDirectory(
    SftpClient sftpClient, string sourceRemotePath, string destLocalPath)
{
    Directory.CreateDirectory(destLocalPath);
    IEnumerable<SftpFile> files = sftpClient.ListDirectory(sourceRemotePath);
    foreach (SftpFile file in files)
    {
        if ((file.Name != ".") && (file.Name != ".."))
        {
            string sourceFilePath = sourceRemotePath + "/" + file.Name;
            string destFilePath = Path.Combine(destLocalPath, file.Name);
            if (file.IsDirectory)
            {
                DownloadDirectory(sftpClient, sourceFilePath, destFilePath);
            }
            else
            {
                using (Stream fileStream = File.Create(destFilePath))
                {
                    sftpClient.DownloadFile(sourceFilePath, fileStream);
                }
            }
        }
    }
}
0
répondu Martin Prikryl 2018-09-20 06:02:20