C# SFTP - 下载文件损坏并在比较文件 SFTP 服务器时显示不同的大小

C# SFTP - download file corrupted and showing different size when compare the file SFTP server

我正在尝试从 SFTP 服务器下载 .zip 和 .xlsx 文件,下载后当我尝试打开 zip 文件时,它说压缩的 zip 文件无效,而且文件大小比 SFTP 大文件大小(远程文件大小)。 我正在使用以下代码:

    string sFTPHost = "sftphost";
    string sFTPDirectory = "file.zip";
    string sFTPUser = "username";
    string sFTPPassword = "pwd";
    string sFTPPort = "22";

    ConnectionInfo ConnNfo = new ConnectionInfo(@sFTPHost, Convert.ToInt32(sFTPPort), @sFTPUser,
        new AuthenticationMethod[]{
            new PasswordAuthenticationMethod(@sFTPUser,@sFTPPassword),
        }
    );

    using (var sftp = new SftpClient(ConnNfo))
    {
        sftp.Connect();

        MemoryStream ms = new MemoryStream();
        sftp.DownloadFile(@sFTPDirectory, ms);
        byte[] feedData = ms.GetBuffer();

        var response = HttpContext.Current.Response;
        response.AddHeader("Content-Disposition", "attachment; filename="filename.zip");
        response.AddHeader("Content-Length", feedData.Length.ToString());
        response.ContentType = "application/octet-stream";
        response.BinaryWrite(feedData);
        sftp.Disconnect();
    }
}

可能是什么问题?

MemoryStream.GetBuffer returns 流的基础数组,其中 can/will 包含 已分配的未使用字节 。例如,返回的 缓冲区 的长度将匹配流的当前 Capacity,但很可能比流的当前 Length

来自documentation

Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused.

您需要改用 ToArray。但是请注意,这会创建一个新数组并将数据复制到其中。

byte[] feedData = ms.ToArray();
var response = HttpContext.Current.Response;
response.AddHeader("Content-Disposition", "attachment; filename=filename.zip");
response.AddHeader("Content-Length", feedData.Length.ToString());
response.ContentType = "application/octet-stream";
response.BinaryWrite(feedData);

或者您应该能够从一个流复制到另一个:

var response = HttpContext.Current.Response;
response.AddHeader("Content-Disposition", "attachment; filename=filename.zip");
response.AddHeader("Content-Length", ms.Length.ToString());
response.ContentType = "application/octet-stream";

// rewind stream and copy to response
ms.Position = 0;
ms.CopyTo(response.OutputStream);