Скачивание фрагментов файлов со смещением с SFTP-сервера с помощью сборки WinSCP .NET.

В настоящее время мы используем сборку WinSCP .NET для взаимодействия с серверами SFTP. Наш вариант использования включает выборку частей файла кусками. Я вижу, что параметр TransferResumeSupportState передачи может использоваться для возобновления загрузки файла, но не дает возможности останавливать и запускать / возобновлять загрузку по мере необходимости.

Другой вариант использования не требует, чтобы часть уже загруженного (обработанного) файла находилась в том же месте (часть загруженного файла обрабатывается и больше не нужна). Чтобы опция TransferResumeSupportState работала, уже загруженная часть файла должна находиться в том же месте.

Есть ли обходной путь для передачи значения смещения файла в GetFiles?

Спасибо,
Vagore


person Varun Gore    schedule 01.03.2017    source источник


Ответы (2)


В качестве альтернативы я бы использовал SSH.NET для этой задачи, где вы можете работать прямо на потоках.

var client = new SftpClient(connectionInfo);

client.Connect();

var sftpFileStream = client.OpenRead(filePath);

sftpFileStream.Seek(previouslyReadOffset, SeekOrigin.Begin);
sftpFileStream.CopyTo(localStream);
person Andrii Litvinov    schedule 02.03.2017

Это невозможно со сборкой 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 основана на создании огромного файла-пустышки за считанные секунды на C #.

person Martin Prikryl    schedule 02.03.2017