使用 SSH.NET 上传到 SFTP 服务器失败,并出现 SftpPathNotFoundException:“系统找不到指定的路径。”

问题描述 投票:0回答:1

我正在尝试使用 Renci SSH.NET 通过 SFTP 上传文件。

连接:

  • 连接到 sFTP 站点,使用 SSH.NET,似乎有效:

    SftpClient
    IsConnected
    返回 true。

  • 但是,
  • 使用 FileZilla 连接会触发此警告:

服务器的主机密钥未知

上传中:

  1. 使用

    SftpClient
    UploadFile
    方法:

    client.UploadFile(fileStream, "/Path/" + fileName, null);
    

    ...我得到一个

    Renci.SshNet.Common.SftpPathNotFoundException

    系统找不到指定的路径。'

    • 我尝试过对路径进行硬编码 - 结果相同。
    • 我尝试过使用
      SftpClient
      WorkingDirectory
      – 但这会翻译成一串看起来像中文的字符,而且也不起作用。
  1. 使用

    SftpClient
    BeginUploadFile
    方法:

    client.BeginUploadFile(fileStream, "/Path/" + fileName, asyncCallback, null, UpdateUploadProgress);
    

    ...我没有收到任何错误/异常,但是:

    • 文件未上传

    • aSyncCallback
      uploadCallback
      似乎不起作用

  2. 使用 FileZilla,我可以很好地上传(使用与上面完全相同的目标路径:

    /Path/Filename.txt


我的代码:

var connectionInfo = new ConnectionInfo(IpAddress,
            Port,
            UserName,
            new PasswordAuthenticationMethod(UserName, Password),
            new PrivateKeyAuthenticationMethod("rsa.key"));
connectionInfo.Encoding = Encoding.Unicode;
using (var client = new SftpClient(connectionInfo))
{
    client.Connect();

    if (client.IsConnected)
    {
        Console.WriteLine("SSH-client is connected");
    }
    var fileStream = new FileStream(FileMaker.GetFullyQualifiedPath(), FileMode.Open);
    client.BufferSize = 4 * 1024;
    string fileName = new FileMaker().GetFileName();
    //client.UploadFile(fileStream, "/Path/" + fileName, null);
    AsyncCallback asyncCallback = new AsyncCallback(NotifyUploadComplete);
    client.BeginUploadFile(fileStream, "/Path/" + fileName, asyncCallback, null, UpdateUploadProgress);
    client.Disconnect();
}

回调处理程序:

private void UpdateUploadProgress(ulong uploaded)
{
    MainViewModel mainViewModel = (MainViewModel)System.Windows.Application.Current.FindResource("mainViewModel");
    mainViewModel.UploadProgress = uploaded;
}

private void NotifyUploadComplete(IAsyncResult result)
{
    MessageBox.Show("File uploaded.", "File uploaded");
}

我做了一个最小的例子并测试了它(相同的结果)。

使用

UploadFile

var connectionInfo = new ConnectionInfo(IpAddress,
            Port,
            UserName,
            new PasswordAuthenticationMethod(UserName, Password),
            new PrivateKeyAuthenticationMethod("rsa.key"));
connectionInfo.Encoding = Encoding.Unicode;
using (var client = new SftpClient(connectionInfo))
{
    client.Connect();

    if (client.IsConnected)
    {
        Console.WriteLine("SSH-client is connected");
    }
    var fileStream = new FileStream(@"C:\File.txt", FileMode.Open);
    client.BufferSize = 4 * 1024;
    client.UploadFile(fileStream, "/SSHUsersPath/File.txt", null);
    //AsyncCallback asyncCallback = new AsyncCallback(NotifyUploadComplete);
    //client.BeginUploadFile(fileStream, "/SSHUsersPath/File.txt", asyncCallback, null, UpdateUploadProgress);
    client.Disconnect();
}

以下是所请求的 FileZilla 日志文件的摘录:

2017-09-21 10:08:36 11252 1 Status: Connected to sshserv.CENSORED.com
2017-09-21 10:08:36 11252 1 Status: Retrieving directory listing...
2017-09-21 10:08:36 11252 1 Command: pwd
2017-09-21 10:08:36 11252 1 Response: Current directory is: "/SSHUsersPath"
2017-09-21 10:08:36 11252 1 Command: ls
2017-09-21 10:08:37 11252 1 Status: Listing directory /SSHUsersPath
2017-09-21 10:08:37 11252 1 Status: Directory listing of "/SSHUsersPath" successful
2017-09-21 10:08:58 11252 3 Status: Connecting to sshserv.CENSORED.com...
2017-09-21 10:08:58 11252 3 Response: fzSftp started, protocol_version=8
2017-09-21 10:08:58 11252 3 Command: open "[email protected]" 22
2017-09-21 10:08:59 11252 3 Command: Trust new Hostkey: Once
2017-09-21 10:09:00 11252 3 Command: Pass: *****
2017-09-21 10:09:00 11252 3 Status: Connected to sshserv.CENSORED.com
2017-09-21 10:09:00 11252 3 Status: Starting upload of C:\File.txt
2017-09-21 10:09:00 11252 3 Command: cd "/SSHUsersPath"
2017-09-21 10:09:01 11252 3 Response: New directory is: "/SSHUsersPath"
2017-09-21 10:09:01 11252 3 Command: put "C:\File.txt" "File.txt"
2017-09-21 10:09:01 11252 3 Command: local:C:\File.txt => remote:/SSHUsersPath/File.txt
2017-09-21 10:09:01 11252 3 Status: File transfer successful, transferred 4 bytes in 1 second
2017-09-21 10:09:01 11252 3 Status: Retrieving directory listing of "/SSHUsersPath"...
2017-09-21 10:09:01 11252 3 Command: ls
2017-09-21 10:09:01 11252 3 Status: Listing directory /SSHUsersPath
2017-09-21 10:09:02 11252 3 Status: Directory listing of "/SSHUsersPath" successful
2017-09-21 10:09:17 11252 1 Status: Deleting "/SSHUsersPath/File.txt"
2017-09-21 10:09:17 11252 1 Command: rm "/SSHUsersPath/File.txt"
2017-09-21 10:09:18 11252 1 Response: rm /SSHUsersPath/File.txt: OK
c# .net ssh sftp ssh.net
1个回答
4
投票

首要问题是:

connectionInfo.Encoding = Encoding.Unicode;

Encoding.Unicode
是 UTF-16。任何 SFTP 服务器都不会处理 UTF-16 编码的文件名。 SFTP 服务器应使用 UTF-8。因此 SSH.NET 默认为
Encoding.UTF8
。如果使用 UTF-8,服务器损坏了文件名中的非 ASCII 字符(
.Encoding
是关于文件名,而不是文件内容),则一定是因为 SFTP 已损坏并使用了某些旧编码。但可以肯定的是,它不是 UTF-16。它而是一些
ISO*
编码或
Windows-*
编码。


另一个问题是,当您使用

BeginUploadFile
时,您不会等待它完成并立即断开连接。

© www.soinside.com 2019 - 2024. All rights reserved.