Можно ли загрузить CSV-файл на SFTP-сервер непосредственно из MemoryStream?

Всякий раз, когда я пытаюсь загрузить файл на SFTP-сервер с расширением файла .csv, единственное, что есть в этом файле, это System.IO.MemoryStream. Если это расширение .txt, оно будет иметь все значения в файле. Я могу вручную преобразовать .txt в .csv, и все будет в порядке. Можно ли загрузить его непосредственно на SFTP-сервер в виде CSV-файла?

Служба SFTP использует библиотеку SSH.NET от Renci.

Использование оператора:

using (var stream = csvFileWriter.Write(data, new CsvMapper()))
{
    byte[] file = Encoding.UTF8.GetBytes(stream.ToString());
    sftpService.Put(SftpCredential.Credentials.Id, file, $"/file.csv");
}

Служба SFTP:

public void Put(int credentialId, byte[] source, string destination)
{
    using (SftpClient client = new SftpClient(GetConnectionInfo(credentialId)))
    {
        ConnectClient(client);

        using (MemoryStream memoryStream = new MemoryStream(source))
        {
            client.BufferSize = 4 * 1024; // bypass Payload error large files
            client.UploadFile(memoryStream, destination);
        }
        DisconnectClient(client);
    }

Решение: csvFilerWriter, который я использовал, вернул Stream, а не MemoryStream, поэтому, заменив csvFileWriter и CsvPut() на MemoryStream, все заработало.

Обновлен оператор using:

using (var stream = csvFileWriter.Write(data, new CsvMapper()))
{
    stream.Position = 0;
    sftpService.CsvPut(SftpCredential.credemtoa;s.Id, stream, $"/file.csv");
}

Обновлена ​​служба SFTP:

public void CsvPut(int credentialId, MemoryStream source, string destination)
{
    using (SftpClient client = new SftpClient(GetConnectionInfo(credentialId)))
    {
        ConnectClient(client);

        client.BufferSize = 4 * 1024; //bypass Payload error large files
        client.UploadFile(source, destination);

        DisconnectClient(client);
    }
}

person ForgotMyName    schedule 02.04.2020    source источник


Ответы (2)


Похоже, что csvFileWriter.Write уже возвращает MemoryStream. И его ToString возвращает строку "System.IO.MemoryStream". Это корень вашей проблемы.

Кроме того, поскольку у вас уже есть MemoryStream, копировать его в еще один MemoryStream будет излишним, загрузив его напрямую. Вы копируете данные снова и снова, это просто пустая трата памяти.

Как это:

var stream = csvFileWriter.Write(data, new CsvMapper());
stream.Position = 0;
client.UploadFile(stream, destination); 

Смотрите также:


Простой тестовый код для загрузки данных в память:

var stream = new MemoryStream();
stream.Write(Encoding.UTF8.GetBytes("this is test"));
stream.Position = 0;

using (var client = new SftpClient("example.com", "username", "password"))
{
    client.Connect();
    client.UploadFile(stream, "/remote/path/file.txt");
}
person Martin Prikryl    schedule 02.04.2020

Вы можете избежать ненужного использования потока памяти следующим образом:

        using (var sftp = new SftpClient(GetConnectionInfo(SftpCredential.GetById(credentialId).Id))))
        {
           sftp.Connect();
           using (var uplfileStream = System.IO.File.OpenRead(fileName))
           {
              sftp.UploadFile(uplfileStream, fileName, true);
           }
           sftp.Disconnect();
        }
person Azzy Elvul    schedule 02.04.2020
comment
Не похоже, что OP загружает физический файл. - person Martin Prikryl; 02.04.2020
comment
Что ты имеешь в виду. Этот фрагмент кода должен быть обернут в метод и должен пройти несколько проверок, прежде чем его можно будет использовать. Я только демонстрирую идею о том, что файл можно открыть как поток, и этот поток можно передать в качестве параметра в UploadFile для загрузки. - person Azzy Elvul; 02.04.2020
comment
Но файла нет. OP загружает данные, сгенерированные непосредственно в память. - person Martin Prikryl; 03.04.2020