使用SSH从SFTP下载文件.网络图书馆

本文关键字:文件 网络 图书馆 下载 SFTP SSH 使用 | 更新日期: 2023-09-27 18:03:48

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

我正在使用SSH。. NET (Renci.SshNet)库与SFTP服务器一起工作。我需要做的是根据今天的日期从SFTP服务器上的特定文件夹中抓取文件。然后将这些文件从SFTP服务器复制到本地驱动器(我的服务器)。

上面是我的代码,但它不工作。有时它说文件不存在,但有时我要下载的文件不在我的本地服务器上,但我需要下载当天上传到远程文件夹的任何文件。

谁来看看有什么问题?我认为这与溪流部分有关。除了上传文件外,我还使用FTP,我采取了一些以前的代码,并认为我可以逆转这个过程,但这不起作用。我使用的代码是基于这个例子的。

使用SSH从SFTP下载文件.网络图书馆

用SSH下载文件的简单工作代码。. NET库是:

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

参见使用SSH下载目录。. NET SFTP .


解释为什么你的代码不能工作:

SftpClient.DownloadFile的第二个参数是一个流,用于写入下载的内容。

传入的是读流而不是写流。此外,您打开读流的路径是一个远程路径,不能与File类一起工作,仅在本地文件上操作。

只是放弃File.OpenRead行,并使用以前的File.OpenWrite调用的结果代替(你现在根本不使用):

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

或者更好的是,使用File.Create来丢弃本地文件可能具有的任何先前的内容。

我不确定你的localFileName是否应该保留完整的路径,或者只是文件名。因此,如果有必要,您可能也需要添加路径(将localFileNamesDir合并?)

虽然这个例子可以工作,但它不是处理流的正确方法…

你需要使用子句来确保关闭文件/流。另外,添加try/catch来处理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.Create(localDirectory + remoteFileName))
                    { 
                        sftp.DownloadFile(remoteDirectory + remoteFileName, file1);
                    }
            }
        }
    }

我的版本的@Merak Marey的代码。我正在检查文件是否已经存在,以及.txt和其他文件的不同下载目录

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

Massimiliano的解决方案有一个问题,会导致文件无法完全下载。必须关闭文件流。这对于加密文件来说尤其是个问题。如果不关闭流,它们不会间歇性地完全解密。

var files = sftp.ListDirectory(remoteVendorDirectory).Where(f => !f.IsDirectory);
foreach (var file in files)
{
    var filename = $"{LocalDirectory}/{file.Name}";
    if (!File.Exists(filename))
    {
        Console.WriteLine("Downloading  " + file.FullName);
        using (var localFile = File.OpenWrite(filename))
            sftp.DownloadFile(file.FullName, localFile);
    }
}

这就解决了我这边的问题。

var files = sftp.ListDirectory(remoteVendorDirectory).Where(f => !f.IsDirectory);
foreach (var file in files)
{
    var filename = $"{LocalDirectory}/{file.Name}";
    if (!File.Exists(filename))
    {
        Console.WriteLine("Downloading  " + file.FullName);
        using (var localFile = File.OpenWrite(filename))
              sftp.DownloadFile(file.FullName, localFile);
    }
}

如果不提供任何具体的错误消息,就很难给出具体的建议。

然而,我正在使用相同的例子,并在文件上获得权限异常。OpenWrite -使用localFileName变量,因为使用Path。GetFile指向的位置显然没有打开文件的权限> C:'ProgramFiles'IIS(Express)'filename.doc

我发现使用System.IO.Path.GetFileName是不正确的,使用System.IO.Path.GetFullPath代替,指向你的文件以"C:'…"

同时在文件资源管理器中打开您的解决方案,并为该文件或保存该文件的任何文件夹授予asp.net权限。那时我就可以下载我的文件了