FtpWebRequest下载文件大小不正确

3
我正在使用以下代码从远程FTP服务器下载文件:
```python import ftplib
ftp = ftplib.FTP('hostname') ftp.login('username', 'password') ftp.cwd('/remote_dir/') with open('local_file', 'wb') as f: ftp.retrbinary('RETR remote_file', f.write) ftp.quit() ```
这个代码使用Python的ftplib库连接到FTP服务器,登录并进入远程目录。然后,它使用`retrbinary()`方法以二进制模式检索远程文件,并将其写入本地文件。最后,关闭FTP连接。
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverPath);

        request.KeepAlive = true;
        request.UsePassive = true;
        request.UseBinary = true;

        request.Method = WebRequestMethods.Ftp.DownloadFile;
        request.Credentials = new NetworkCredential(userName, password);                

        using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
        using (Stream responseStream = response.GetResponseStream())
        using (StreamReader reader = new StreamReader(responseStream))
        using (StreamWriter destination = new StreamWriter(destinationFile))
        {
            destination.Write(reader.ReadToEnd());
            destination.Flush();
        }

我正在下载的文件是一个dll文件,我的问题是它被这个进程以某种方式修改了。我知道这是因为文件大小在增加。我怀疑代码的这一部分有问题:

        destination.Write(reader.ReadToEnd());
        destination.Flush();

有人能提供任何关于可能出了什么问题的想法吗?
1个回答

12
StreamReaderStreamWriter 处理字符数据,所以您需要将流从字节解码为字符,然后再次编码为字节。 DLL 文件包含二进制数据,因此这种往返转换会引入错误。 您希望直接从 responseStream 对象读取字节,并写入未包装在 StreamWriter 中的 FileStream

如果您使用的是 .NET 4.0,则可以使用 Stream.CopyTo,否则您将不得不手动复制流。 此 StackOverflow 问题 具有复制流的良好方法:

public static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[32768];
    while (true)
    {
        int read = input.Read(buffer, 0, buffer.Length);
        if (read <= 0)
            return;
        output.Write(buffer, 0, read);
    }
}

所以,你的代码将会是这样的:

using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (FileStream destination = File.Create(destinationFile))
{
    CopyStream(responseStream, destination);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接