简体   繁体   中英

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

I am trying to download.zip and.xlsx files from SFTP server,after downloading when I tried to open the zip file, it saying the compressed zip files is invalid and also the files size is high compared with the SFTP file size(remote file size). I am using the below code:

    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();
    }
}

What could be the issue?

MemoryStream.GetBuffer returns the underlying array of the stream which can/will contain allocated, unused bytes . For example the length of the returned buffer will match the stream's current Capacity , but will most likely be larger than the stream's current Length .

From the 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.

You will need to use ToArray instead. Note however that this creates a new array and copies the data into it.

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);

Alternatively you should be able to copy from one stream to the other:

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM