6

我正在尝试使用 SharpSSH 从远程 SFTP 服务器获取文件,并且我想将其作为流读取。

我发现:

  • Sftp,它有一个Get将它保存到本地文件的方法 -- 关闭

  • class SshStream,它可能会做我想要的,但似乎与之脱节,Sftp所以我可能不得不自己实现 SFTP 部分(??)

  • class ChannelSftp,它实现了类似的 SFTP 方法get(String, OutputStream),这似乎很完美,除了它是一个低级类,而且对我来说如何实例化它一点也不明显

看起来如果Sftp' 的ChannelSftp SftpChannel财产不是私有的,我可以使用它,一切都会很完美。不过,如果可能的话,我想避免破解 SharpSSH。

我错过了什么吗?

4

1 回答 1

8

我解决了一些问题,并对其进行了测试。试一试,随意按摩 API。

首先,您需要提出一种方法,该方法允许您利用ChannelSftp调用OutputStreams 而不是目标文件名的方法。如果你不想使用反射来做,那么将这个方法添加到 Sftp 类并重新编译 SharpSSH。

public void GetWithStream(string fromFilePath, Tamir.SharpSsh.java.io.OutputStream stream)
{
    cancelled = false;
    SftpChannel.get(fromFilePath, stream, m_monitor);
}

Stream接下来,为与兼容的类创建一个包装器,Tamir.SharpSsh.java.io.OutputStream如下所示:

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

有了这些成分,您现在可以使用 OpenSSH 将其数据流式传输到您选择的流中,如下所示,使用FileStream.

使用 System.IO;使用 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();
    }
}
于 2010-07-31T03:49:22.793 回答