tinonetic
tinonetic

Reputation: 8034

Downloading and returning a non blocking stream of data using SSH.Net

I am using the ssh.net library for performing SFTP operations to work with large data files (>=500MB)

I am having an issue with how to return the data in a non-blocking way.

The ftpClient.DownloadFile() method signature is ok, when writing to a file or if there's some way I can instantiate the stream, but am having problems on how to use it when I want to return a stream without blocking.

All the examples I have seen so far will be writing the download to a Filestream. Nothing that just returns a stream

With .Net's built-in FTP, you just use response.GetResponseStream(), and it streams back the data, without blocking.

The only way round to using it in a return statement was writing to a temporarity file. But this results in it being a blocking operation.

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

I don't want it to block but to stream back the data.

I also would like to avoid creating a temporary file.

Is there an alternative implementation to make it stream back the data?

Or is there an alternative stream I can instantiate(except for MemoryStream), that would work with large files?

Upvotes: 6

Views: 3629

Answers (2)

mdk
mdk

Reputation: 127

Many years later, I had this same issue that took longer to figure out than I'd care to admit. This was one of the top search results, so here's an actual answer: It turns out that SSH.NET does indeed expose an SftpFileStream, just with different methods that you might not see if you're looking for "Download". Instead of sftpClient.DownloadFile(sourceFile, stream), use sftpClient.OpenRead(sourceFile). That will allow you to work directly with the streamed data.

Upvotes: 1

Wojciech Radosz
Wojciech Radosz

Reputation: 49

This is old question, but I had similar issue. If you want to get the stream directly you can write to 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

If you want to download file, you can make it in separate thread or as asynchronous call and then call the delegate:

_sftpClient.DownloadFile(ftpFile.FullName, fileBody, YourActionDelegateHere);

Upvotes: 4

Related Questions