Загрузка и возврат неблокирующего потока данных с использованием SSH.Net

Я использую библиотеку ssh.net для выполнения операций SFTP для работы с большими файлами данных (>= 500 МБ)

У меня возникла проблема с возвратом данных неблокирующим способом.

Сигнатура метода ftpClient.DownloadFile() в порядке при записи в файл или если есть какой-то способ создать экземпляр потока, но у меня возникают проблемы с тем, как его использовать, когда я хочу вернуть поток без блокировки.

Все примеры, которые я видел до сих пор, будут записывать загрузку в файл Filestream. Ничего, что просто возвращает поток

Со встроенным FTP .Net вы просто используете response.GetResponseStream(), и он возвращает данные без блокировки.

Единственным способом использования его в операторе возврата была запись во временный файл. Но это приводит к тому, что это блокирующая операция.

        var tmpFilename = "temp.dat";
        int bufferSize = 4096;
        var sourceFile = "23-04-2015.dat";

        using (var stream = System.IO.File.Create(tmpFilename , bufferSize, System.IO.FileOptions.DeleteOnClose))
        {
            sftpClient.DownloadFile(sourceFile, stream);
            return stream;
        }

Я не хочу, чтобы он блокировался, а чтобы передавать данные обратно.

Я также хотел бы избежать создания временного файла.

Есть ли альтернативная реализация для обратного потока данных?

Или есть альтернативный поток, который я могу создать (кроме MemoryStream), который будет работать с большими файлами?


person user919426    schedule 23.04.2015    source источник
comment
Загрузка осуществляется по какому протоколу (например, HTTP, TCP)?   -  person Vinicius Ottoni    schedule 27.04.2015
comment
Я не понимаю вашего вопроса. Как появляется TCP, поскольку это не прикладной протокол .... Не думайте, что существует такая вещь, как SFTP через HTTP .... Но это SFTP через порт 22.   -  person user919426    schedule 28.04.2015
comment
Я думал, что вы хотите сначала загрузить из SFTP в свое приложение (это может быть в WPF или ASP.NET, т.е.). Но загрузка прямая, верно?   -  person Vinicius Ottoni    schedule 28.04.2015


Ответы (2)


Это старый вопрос, но у меня была похожая проблема. Если вы хотите получить поток напрямую, вы можете написать в MemoryStream.

SftpClient _sftpClient;
_sftpClient = new SftpClient("sftp.server.domain", "MyLoginHere", "MyPasswordHere");
Stream fileBody = new MemoryStream();
_sftpClient.DownloadFile(ftpFile.FullName, fileBody);
fileBody.Position = 0; //dont forget to set the stream position back to beginning

Если вы хотите загрузить файл, вы можете сделать это в отдельном потоке или как асинхронный вызов, а затем вызвать делегата:

_sftpClient.DownloadFile(ftpFile.FullName, fileBody, YourActionDelegateHere);
person Wojciech Radosz    schedule 24.10.2017
comment
Это может быть хорошо для небольших файлов, но это наименее эффективно, поскольку вы не используете буферизацию... вы получите OutOfMemoryExceptions для больших файлов. - person user919426; 24.10.2017

Много лет спустя у меня возникла та же самая проблема, на решение которой ушло больше времени, чем я хотел бы признать. Это был один из самых популярных результатов поиска, поэтому вот фактический ответ: оказывается, SSH.NET действительно предоставляет SftpFileStream, просто с помощью других методов, которые вы можете не увидеть, если ищете «Загрузить». Вместо sftpClient.DownloadFile(sourceFile, stream) используйте sftpClient.OpenRead(sourceFile). Это позволит вам работать напрямую с потоковыми данными.

person mdk    schedule 20.02.2021