使用WinSCP .NET程序集

时间:2017-03-01 22:41:37

标签: c# .net sftp winscp winscp-net

我们目前正在使用WinSCP .NET程序集与SFTP服务器进行交互。我们的用例涉及以块的形式获取文件的一部分。我看到TransferResumeSupportState传输选项可用于恢复文件下载,但不能在需要时自由停止和启动/恢复下载。

另一个用例之一不要求已下载(处理)的文件部分位于同一位置(已下载的文件的一部分已被处理,不再需要)。要使TransferResumeSupportState选项起作用,已经下载的文件部分必须存在于同一位置。

是否有解决方法将文件偏移值传递给GetFiles

谢谢,
Vagore

2 个答案:

答案 0 :(得分:2)

作为替代方案,我会使用SSH.NET执行此任务,您可以直接在流上操作。

var client = new SftpClient(connectionInfo);

client.Connect();

var sftpFileStream = client.OpenRead(filePath);

sftpFileStream.Seek(previouslyReadOffset, SeekOrigin.Begin);
sftpFileStream.CopyTo(localStream);

答案 1 :(得分:1)

WinSCP .NET程序集无法实现这一点。

您所能做的就是通过

欺骗WinSCP
  • 创建一个具有您要跳过的大小的虚拟本地文件
  • TransferOptions.OverwriteMode设置为OverwriteMode.Resume(请注意,它不是TransferResumeSupportState)并将创建的TransferOptions传递给Session.GetFiles
long offset = 1024 * 1024;
const string remotePath = "/remote/path";

// Quickly create an dummy temporary local file with the desired size
string localPath = Path.GetTempFileName();
using (FileStream fs = File.Create(localPath))
{
    fs.SetLength(offset);
}

// "Resume" the download
TransferOptions transferOptions = new TransferOptions();
transferOptions.OverwriteMode = OverwriteMode.Resume;
session.GetFiles(
    RemotePath.EscapeFileMask(remotePath), localPath, false, transferOptions).Check();

// Read the downloaded chunk 
byte[] chunk;
using (FileStream fs = File.OpenRead(localPath))
{
    fs.Seek(offset, SeekOrigin.Begin);

    int downloaded = (int)(fs.Length - offset);
    chunk = new byte[downloaded];
    fs.Read(chunk, 0, downloaded);
}

// Delete the temporary file
File.Delete(localPath);

SetLength技巧基于Creating a Huge Dummy File in a Matter of Seconds in C#