2010-07-07 61 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); 
}