sshnet / sshnet/SSH.NET

how can i download a directory from a server via SFTP/SCP to a zip file

Aperta
#948 7 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

question third-party
Lingua principale
C#
Stelle
4.4k
Fork
993
Merge medio
9g 21h
PR unite (30g)
1

Descrizione

I don't know how to do this using SSH.NET


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Renci.SshNet;
using Renci.SshNet.Sftp;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {

            var connectionInfo = new ConnectionInfo("192.168.133.13", "user",
                                        new PasswordAuthenticationMethod("isaque.neves", "pass"));
            using (var client = new SftpClient(connectionInfo))
            {
                client.Connect();
                DownloadDirectory(client,"/var/www/teste", @"C:\MyCsharpProjects\fsbackup\download");
             
            }

            Console.WriteLine("end");
        }

        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);
                        }
                    }
                }
            }
        }
    }
}


I already did it in rust, but I don't know how to do it using SSH.NET

pub fn filetransfer_recv_dir_as_zip(&mut self, dir_to_copy: &FsDirectory, local_path: &Path, output_file_name: &str) -> FileTransferResult<()> {
        let start =  Instant::now();
        //obter lista de diretorio recursivamente
        match self.client.list_dir_recursively(&dir_to_copy.abs_path.clone()) {
            Ok(it) => {
                let duration = start.elapsed();
                info!("Time elapsed in list_dir_recursively {:?}", duration);

                let dst_file_writer = File::create(local_path.join(output_file_name)).unwrap();
                let mut zip_writer = zip::ZipWriter::new(dst_file_writer);

                let mut buffer = Vec::new();

                for entry in it {
                    let options = zip::write::FileOptions::default()
                        .compression_method(zip::CompressionMethod::Stored)
                        .unix_permissions(0o755);

                    match entry {
                        FsEntry::File(remote) => {
                            let path = &remote.abs_path;
                            //remove a parte inicial do caminho
                            let name = path.strip_prefix(&dir_to_copy.abs_path).unwrap();
                            //debug!("source: {}",name.display());

                            match self.client.recv_file(&remote) {
                                Ok(mut rhnd) => {
                                    #[allow(deprecated)]
                                    match zip_writer.start_file_from_path(name, options) {
                                        Ok(re) => {}
                                        Err(err) => {
                                            self.log(
                                                LogLevel::Error,
                                                format!(
                                                    "Error on zip_writer.start_file_from_path : {:?}",
                                                    err
                                                ),
                                            );
                                            return Err(FileTransferError::new(FileTransferErrorType::ZipCompressError));
                                        }
                                    }

                                    match  rhnd.read_to_end(&mut buffer) {
                                        Ok(re) => {}
                                        Err(err) => {
                                            self.log(
                                                LogLevel::Error,
                                                format!(
                                                    "Error on read_to_end : {}",
                                                    err
                                                ),
                                            );
                                            return Err(FileTransferError::new(FileTransferErrorType::ProtocolError));
                                        }
                                    }

                                    match  zip_writer.write_all(&*buffer) {
                                        Ok(re) => {}
                                        Err(err) => {
                                            self.log(
                                                LogLevel::Error,
                                                format!(
                                                    "Error zip_writer.write_all : {}",
                                                    err
                                                ),
                                            );
                                            return Err(FileTransferError::new(FileTransferErrorType::ZipCompressError));
                                        }
                                    }


                                    buffer.clear();
                                }
                                Err(err) if err.kind() == FileTransferErrorType::UnsupportedFeature => {
                                    error!("FileTransferErrorType::UnsupportedFeature");
                                }
                                Err(err) => {
                                    error!("FileTransferError {:?}",err);
                                }
                            }
                        }
                        FsEntry::Directory(dir) => {}
                    }
                }
                zip_writer.finish().unwrap();

                let duration = start.elapsed();
                info!("Time elapsed filetransfer_recv_dir_as_zip {:?}", duration);
                Ok(())
            }
            Err(err) => {
                self.log(
                    LogLevel::Error,
                    format!(
                        "Failed list dir recursively \"{}\": {}",
                        dir_to_copy.abs_path.display(),
                        err
                    ),
                );
                Err(err)
            }
        }
    }

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Non viene indicato alcun file del repository né alcun test. Inizia con l’esempio di SftpClient e DownloadDirectory nell’issue, poi chiarisci se si tratta di una richiesta di documentazione o di una funzionalità della libreria e definisci il comportamento previsto dell’archivio prima di identificare i passaggi di validazione.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
csharp
Ambito
networking
Tipo di issue
Documentazione
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Da chiarire
Idoneità per principianti
20/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.