I worked something out, and tested it out. Give it a try, and feel free to massage the API.
First off, you will need to surface up a method that allows you to take advantage of the ChannelSftp
methods that call for OutputStream
s instead of destination file names. If you don't want to use reflection to do it, then add this method to the Sftp class and recompile SharpSSH.
public void GetWithStream(string fromFilePath, Tamir.SharpSsh.java.io.OutputStream stream)
{
cancelled = false;
SftpChannel.get(fromFilePath, stream, m_monitor);
}
Next, create a wrapper for the Stream
class that is compatible with Tamir.SharpSsh.java.io.OutputStream
, such as the one below:
using System.IO;
using Tamir.SharpSsh.java.io;
public class GenericSftpOutputStream : OutputStream
{
Stream stream;
public GenericSftpOutputStream(Stream stream)
{
this.stream = stream;
}
public override void Write(byte[] buffer, int offset, int count)
{
stream.Write(buffer, offset, count);
}
public override void Flush()
{
stream.Flush();
}
public override void Close()
{
stream.Close();
}
public override bool CanSeek
{
get { return stream.CanSeek; }
}
public override long Seek(long offset, SeekOrigin origin)
{
return stream.Seek(offset, origin);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (this.stream != null)
{
this.stream.Dispose();
this.stream = null;
}
}
}
With those ingredients, you can now use OpenSSH to stream its data to the stream of your choice, as demonstrated below with a FileStream
.
using System.IO;
using Tamir.SharpSsh;
class Program
{
static void Main(string[] args)
{
var host = "hostname";
var user = "username";
var pass = "password";
var file = "/some/remote/path.txt";
var saveas = @"C:\some\local\path";
var client = new Sftp(host, user, pass);
client.Connect();
using (var target = new GenericSftpOutputStream(File.Open(saveas, FileMode.OpenOrCreate)))
{
client.GetWithStream(file, target);
}
client.Close();
}
}