簡體   English   中英

在 C# 中使用 SFTP 將 MemoryStream 從 Amazon S3 存儲桶發送到遠程服務器時獲取“無效路徑”

[英]Getting "Invalid path" when sending MemoryStream from Amazon S3 bucket to a remote server using SFTP in C#

我正在處理從 Amazon S3 存儲桶中檢索文件然后使用 SFTP 將其發送到遠程服務器的邏輯。

但是,我無法發送文件,因為我沒有路徑值 - 即,因為我的文件在 S3 中,所以我沒有本地計算機的路徑。

這是我發送文件的方法——它在一個名為SftpService的類中:

public async Task SendFile(SftpRequest request, CancellationToken cancellationToken = default)
{
    // Connect to server
    SftpClient client = new SftpClient(request.Host, request.Port, request.Username, request.Password);
    client.Connect();

    if (!client.IsConnected)
    {
        throw new SftpClientException("SFTP Connection was not complete.");
    }

    // Create an object of File Stream and pass a temp file path.
    var tempFilePath = Path.GetTempFileName();
    FileStream fileStream = new FileStream(tempFilePath, FileMode.Open);

    // Copy the MemoryStream (from S3) to the FileStream
    request.RefundFile.CopyTo(fileStream);
    fileStream.Close();

    // Upload the file. [TBD] What's the path for the file? (it is a MemoryStream)
    client.UploadFile(fileStream, tempFilePath);

    // Dispose the object by calling dispose method of sftpClient once the file has uploaded.
    client.Dispose();
}

現在,我正在嘗試對此方法執行測試(使用 NUnit)。

[SetUp]
public void Setup()
{
    _sut = new SftpService(); //class
}

[Test]
public async Task SftpService_ShouldSendFileToServer_Success()
{
    var request = MockSftpRequest();

    await _sut.SendFile(request);
}

private SftpRequest MockSftpRequest()
{
    var serverMock = new ServerOptions()
    {
        BaseAddress = "195.144.107.198",
        Username = "demo",
        Password = "password",
    };

    // Create a mock MemoryStream
    var s3FileMock = new MemoryStream(Encoding.UTF8.GetBytes("This is a mock of the s3 file."));

    SftpRequest request = new SftpRequest(serverMock)
    {
        RefundFile = refundFileMock,
        Port = 22,
    };

    return request;
}

運行測試時,出現此錯誤:

消息:Renci.SshNet.Common.SftpPathNotFoundException:無效路徑。


所以,我的問題是:如何在沒有路徑的情況下通過 SFTP 發送MemoryStream

SftpClient.UploadFile的兩個參數都錯了。

  1. 您的直接問題是您將本地路徑傳遞給SftpClient.UploadFile的第二個參數。 為什么? 顯然,一個參數必須用於本地文件/數據,另一個參數用於遠程 您已經將本地數據傳遞給第一個參數。 所以SftpClient.UploadFile不再需要本地路徑。 它需要遠程路徑。

  2. 為什么要將[Memory]Stream保存到臨時文件只是為了將文件作為另一個[File]Stream打開以將其傳遞給SftpClient.UploadFile 立即將MemoryStream傳遞給SftpClient.UploadFile

client.UploadFile(request.RefundFile, "/remote/path/file");

相關問題:使用 SSH.NET 將數據從內存上傳到 SFTP 服務器

[解決方案]在 Martin Prikryl 回答后,我將我的代碼更正為以下內容。

public async Task SendFile(SftpRequest request, CancellationToken cancellationToken = default)
{
    // Connect to server
    SftpClient client = new SftpClient(request.Host, request.Port, request.Username, request.Password);
    client.Connect();

    if (!client.IsConnected)
    {
        throw new SftpClientException("SFTP Connection was not complete.");
    }

    // Upload the file.
    client.UploadFile(request.RefundFile, Path.Combine(request.ServerOptions.RemoteDirectory, request.RefundFileName));

    // Dispose the object by calling dispose method of sftpClient once the file has uploaded.
    client.Dispose();
}

這樣它就可以毫無問題地工作。 謝謝!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM