通过 FtpWebRequest 检索的文件与服务器上的源文件不同

File Retrieved via FtpWebRequest Is Different Than Source File On Server

我正在使用 Microsoft 帮助页面中提供的示例代码从 FTP 服务器检索 GZip 文件:

https://msdn.microsoft.com/en-us/library/ms229711(v=vs.110).aspx

代码效果很好!建立连接,检索文件并保存到我的目标路径中。

问题在于此代码创建的文件与源 FTP 站点上的文件不同。例如,我可能有一个 288,936 字节的源文件,但这段代码创建的文件是 532,550 字节。如果我们处理的是纯文本文件,那可能没问题,但由于这些是 GZip 文件,我无法解压缩它们,因为它们已损坏,并产生以下错误:

The magic number in GZip header is not correct. Make sure you are passing in a GZip stream.

我知道这是 FTP 下载代码中某处的错误,因为我可以使用不同的 FTP 客户端下载文件并正确解压缩文件。

这是确切的源代码。我已经创建了自己的 "helper" 方法来连接到 FTP 服务器并将远程文件下载到本地文件夹目标。

    public static void TransferFileFromFtp(string uri, string username, string password, string folderName, string fileName, DirectoryInfo importFolder)
    {
        FtpWebRequest ftp = GetFtpConnection(uri, username, password, folderName + "/" + fileName);
        ftp.KeepAlive = false;
        ftp.Method = WebRequestMethods.Ftp.DownloadFile;
        FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();

        Stream responseStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(responseStream);

        FileInfo file = new FileInfo(Path.Combine(importFolder.FullName, fileName));
        using (Stream fileStream = file.OpenWrite())
        using (StreamWriter fileWriter = new StreamWriter(fileStream))
        {
            fileWriter.Write(reader.ReadToEnd());
        }

        reader.Close();
        response.Close();
    }


    //Helper method to create an FTP connection...
    private static FtpWebRequest GetFtpConnection(string uri, string username, string password, string folderName)
    {
        FtpWebRequest ftp;

        if (folderName == null || folderName.Length == 0) ftp = (FtpWebRequest)FtpWebRequest.Create(uri);
        else ftp = (FtpWebRequest)FtpWebRequest.Create(uri + "/" + folderName);
        ftp.Credentials = new System.Net.NetworkCredential(username, password);

        return ftp;
    }

我错过了什么?我怎样才能准确下载我的文件?

FtpWebRequest 和 FtpWebResponse 使用起来很痛苦。

System.Net.WebClient 对于简单的下载来说更容易使用。

这是一个从 SEC 的 EDGAR FTP 站点下载 GZip 文件的示例:

using System.Net;
...
var webClient = new WebClient();
webClient.Credentials = new NetworkCredential("anonymous", "janeDoe@contoso.com");
webClient.DownloadFile("ftp://ftp.sec.gov/edgar/daily-index/2012/QTR4/company.20121003.idx.gz", @"c:\temp\destination.gz");

对于更高级的 FTP 操作,CodePlex 上的 System.Net.FtpClient 项目是一个不错的选择。它可以通过 NuGet 轻松安装。