2010-07-07 42 views
3

我使用下面的代码从远程FTP服务器下载文件:的FtpWebRequest下载文件大小不正确

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

任何人都可以提供任何想法,以什么可能是错的?

回答

11

StreamReaderStreamWriter使用字符数据,因此您正在解码流从字节到字符,然后再次将其编码回字节。一个dll文件包含二进制数据,所以这个往返转换会引入错误。您希望直接从responseStream对象中读取字节,并将其写入FileStream中,但未包含在StreamWriter中。

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

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