使用SharpSSH流式传输文件

6
我正在尝试使用SharpSSH从远程SFTP服务器获取文件,并希望将其作为流读出。我发现以下内容:
- 类“Sftp”具有“Get”方法,该方法将其保存到本地文件 - 关闭。 - 类“SshStream”可能做我想要的事情,但似乎与“Sftp”不相关,因此我可能必须自己实现SFTP部分(??)。 - 类“ChannelSftp”实现了SFTP方法,例如“get(String,OutputStream)”,看起来非常完美,但它是一个低级类,我甚至不知道如何实例化它。
如果“Sftp”的“ChannelSftp SftpChannel”属性不是私有的,那么我可以使用它,一切都将完美无缺。但我希望尽可能避免修改SharpSSH。我有什么遗漏吗?
1个回答

8

我做了一些工作并进行了测试。试用一下,随意调用API。

首先,您需要提供一个方法,以便使用ChannelSftp方法而不是目标文件名来调用OutputStream。如果您不想使用反射来完成此操作,则可以将此方法添加到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演示的那样。

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

我知道这是一个老问题,但我正在向SharpSSH添加一些代码并简化一些部分,我将尝试在https://bitbucket.org/mattgwagner/sharpssh中打补丁。谢谢! - MattGWagner
@Matt - 太棒了!感谢你的提醒,也很高兴你能做出贡献。 - kbrimington
我遇到了以下错误 无法找到路径'C:\Folder\'的一部分。我该如何解决? - Illep
这个流支持寻址吗?我能用它下载文件的部分吗? - Mathias Lykkegaard Lorenzen
@Matthias - 不确定,但通常当您以这种方式包装流时,外部流支持底层流支持的任何内容。我不知道的是:如果您寻求将位置定位在1000处,那么这个位置是在安全数据还是未加密数据中的位置。幸运的是,您可以轻松尝试而不需要太多的努力。 - kbrimington
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接