Obter os ficheiros do SFTP com SSH.NET biblioteca

string host = @"ftphost";
string username = "user";
string password = "********";
string localFileName  = System.IO.Path.GetFileName(@"localfilename");
string 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("."))
        {
            string remoteFileName = file.Name;
            if (file.LastWriteTime.Date == DateTime.Today)

            Console.WriteLine(file.FullName);

            File.OpenWrite(localFileName);

            string sDir = @"localpath";

            Stream file1 = File.OpenRead(remoteDirectory + file.Name);
            sftp.DownloadFile(remoteDirectory, file1);
        }
    }
}

estou a usar SSH.NET (Renci.SshNet) biblioteca para trabalhar com um servidor SFTP. O que eu preciso fazer é pegar arquivos de uma pasta específica no servidor SFTP com base na data de hoje. Em seguida, copie esses arquivos do servidor SFTP para uma unidade local um servidor meu.

Acima está o código que tenho, mas não está a funcionar. Às vezes diz que o arquivo não existe, mas às vezes os arquivos que eu vou estar baixando não será em meus servidores locais, mas eu preciso baixar quaisquer arquivos foram enviados para o pasta remota para aquele dia.

Alguém pode ver o que se passa? Acho que tem algo a ver com a parte do Riacho. Eu tenho trabalhado com FTP muito além de Upload de arquivos que eu peguei algum código anterior que eu tinha e pensei que eu poderia reverter o processo, mas que não está funcionando. O código que usei é baseado neste exemplo .

Author: Martin Prikryl, 2014-05-16

4 answers

Um código de trabalho simples para descarregar um ficheiro com SSH.NET a Biblioteca é:

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

Ver também a transferir uma pasta com SSH.NET SFTP in C#.


para explicar, por que seu código não funciona:

o segundo parâmetro de SftpClient.DownloadFile é um stream para onde escrever um conteúdo baixado.

Você está passando em um riacho de leitura em vez de um riacho de escrita. E além disso, o caminho com o qual você está abrindo o fluxo de leitura é um caminho remoto, o que não pode funcionar com a classe File operando apenas em arquivos locais.

basta descartar a linha File.OpenRead e usar um resultado da chamada anterior File.OpenWrite em vez disso (que você não está usando de todo agora):

Stream file1 = File.OpenWrite(localFileName);

sftp.DownloadFile(file.FullName, file1);

ou melhor ainda, use File.Create para descartar qualquer conteúdo anterior que o arquivo local possa ter.

Não tenho a certeza se o teu localFileName é suposto manter o caminho completo, ou apenas o nome do ficheiro. Por isso, poderá ter de adicionar um caminho também, se necessário (combinar localFileName com sDir?)

 27
Author: Martin Prikryl, 2018-09-20 05:54:13

Enquanto o exemplo funciona, não é a maneira correcta de lidar com as correntes...

É necessário assegurar o encerramento dos ficheiros/transmissões com a Cláusula Usando.. Além disso, adicione tentar/pegar para lidar com erros de IO...

       public void DownloadAll()
    {
        string host = @"sftp.domain.com";
        string username = "myusername";
        string password = "mypassword";

        string remoteDirectory = "/RemotePath/";
        string localDirectory = @"C:\LocalDriveFolder\Downloaded\";

        using (var sftp = new SftpClient(host, username, password))
        {
            sftp.Connect();
            var files = sftp.ListDirectory(remoteDirectory);

            foreach (var file in files)
            {
                string remoteFileName = file.Name;
                if ((!file.Name.StartsWith(".")) && ((file.LastWriteTime.Date == DateTime.Today))

                    using (Stream file1 = File.OpenWrite(localDirectory + remoteFileName))
                    { 
                        sftp.DownloadFile(remoteDirectory + remoteFileName, file1);
                    }
            }

        }
    }
 13
Author: Merak Marey, 2016-09-10 23:24:25
A minha versão do código de @Merak Marey. Estou verificando se os arquivos já existem e diferentes diretórios de download para .txt e outros ficheiros
        static void DownloadAll()
    {
        string host = "xxx.xxx.xxx.xxx";
        string username = "@@@";
        string password = "123";string remoteDirectory = "/IN/";
        string finalDir = "";
        string localDirectory = @"C:\filesDN\";
        string 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)
            {

                string 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();

        }
 2
Author: Tasos Mansour, 2017-05-30 09:40:02
Sem você fornecer qualquer mensagem de erro específica, é difícil dar sugestões específicas.

No entanto, eu estava usando o mesmo exemplo e estava recebendo uma exceção de permissões em Arquivo.OpenWrite-usando a variável localFileName, porque usando Path.O GetFile estava a apontar para uma localização que obviamente não teria permissões para abrir um ficheiro > C:\ProgramFiles\IIS (expresso)\nome do ficheiro.doc

Descobri que usar o System. IO. Path. GetFileName não está correcto, use System. IO. Path. GetFullPath em alternativa, indique o seu ficheiro a começar por " C:\..."

Também abra a sua solução no FileExplorer e conceda permissões para asp.net para o ficheiro ou quaisquer pastas que guardem o ficheiro. Consegui descarregar o meu ficheiro nessa altura.

 0
Author: Doug, 2015-06-17 21:47:12