Загрузка на SFTP-сервер с SSH.NET завершается с ошибкой SftpPathNotFoundException: "Системе не удается найти указанный путь".

Я пытаюсь загрузить файл через SFTP, используя Renci SSH.NET.

Подключение:

  • Подключение к sFTP-сайту, используя SSH.NET, похоже работает: SftpClient"s IsConnected возвращает истину.

  • Однако при подключении с использованием FileZilla выдается следующее предупреждение:

    Ключ хоста сервера неизвестен

Загрузка:

1) Использование SftpClient"s UploadFile метод:

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

... я получаю Renci.SshNet.Common.SftpPathNotFoundException: 'Система не может найти указанный путь.'

  • Я пробовал жестко закодировать путь - тот же результат.
  • Я пытался использовать SftpClient"s WorkingDirectory - но это переводится в строку китайских символов и тоже не работает.

2) Использование SftpClient"s BeginUploadFile метод:

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

... я не получаю ошибок / исключений, но:

  • файл не загружен

  • aSyncCallback а также uploadCallback не похоже на работу

3) используя 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 Статус: подключен к sshserv.CENSORED.com 2017-09-21 10:08:36 11252 1 Статус: получение списка каталогов... 2017-09-21 10:08:36 11252 1 команда: pwd 2017-09-21 10:08:36 11252 1 Ответ: текущий каталог: "/SSHUsersPath" 2017-09-21 10:08:36 11252 1 команда: ls 2017-09-21 10:08:37 11252 1 Статус: каталог листинга /SSHUsersPath 2017-09-21 10:08:37 11252 1 Статус: список каталогов "/ SSHUsersPath" успешен 2017-09-21 10:08:58 11252 3 Статус: подключение к sshserv.CENSORED.com... 2017-09-21 10:08:58 11252 3 Ответ: fzSftp запущен, protocol_version=8 2017-09-21 10:08:58 11252 3 Команда: открыть "CENSORED@sshserv.CENSORED.com" 22 2017-09-21 10:08:59 11252 3 Команда: Доверять новому ключу хоста: Один раз 2017-09-21 10:09:00 11252 3 Команда: Пропустить: ***** 2017-09-21 10:09:00 11252 3 Статус: подключен к sshserv.CENSORED.com 2017-09-21 10:09:00 11252 3 Статус: начинается загрузка C:\File.txt 2017-09-21 10:09:00 11252 3 Команда: cd "/SSHUsersPath" 2017-09-21 10:09:01 11252 3 Ответ: Новый каталог: "/SSHUsersPath" 2017-09-21 10:09:01 11252 3 Команда: положить "C:\File.txt" "File.txt" 2017-09-21 10:09:01 11252 3 Команда: локальная:C:\File.txt => remote:/SSHUsersPath/File.txt 2017-09-21 10:09:01 11252 3 Статус: Передача файла прошла успешно, 4 байта переданы за 1 секунду 2017-09-21 10:09:01 11252 3 Статус: получение списка каталогов "/SSHUsersPath"... 2017-09-21 10:09:01 11252 3 Команда: ls 2017-09-21 10:09:01 11252 3 Статус: список directory /SSHUsersPath 2017-09-21 10:09:02 11252 3 Статус: список каталогов "/ SSHUsersPath" успешно 2017-09-21 10:09:17 11252 1 Статус: удаление "/SSHUsersPath/File.txt" 2017-09-21 10:09:17 11252 1 команда: rm "/SSHUsersPath/File.txt" 2017-09-21 10:09:18 11252 1 Ответ: rm /SSHUsersPath/File.txt: OK

1 ответ

Решение

Основная проблема заключается в следующем:

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, вы не дожидаетесь его окончания и сразу же отключаете.

Другие вопросы по тегам