2010-07-07 12 views
3

J'utilise le code suivant pour télécharger un fichier depuis un serveur FTP distant:FtpWebRequest Télécharger le fichier Taille incorrecte

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

Le fichier que je suis le téléchargement est une dll et mon problème est qu'il est d'être modifié par ce processus d'une certaine manière. Je le sais parce que la taille du fichier augmente. Je soupçonne que cette section de code est en faute:

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

Quelqu'un peut-il offrir des idées sur ce qui peut-être tort?

Répondre

11

StreamReader et StreamWriter de travailler avec les données de caractères, de sorte que vous êtes en train de décoder le flux d'octets en caractères, puis de le coder à nouveau en octets. Un fichier dll contient des données binaires, donc cette conversion aller-retour introduira des erreurs. Vous voulez lire des octets directement à partir de l'objet responseStream et écrire dans un FileStream qui n'est pas enveloppé dans un StreamWriter.

Si vous utilisez .NET 4.0, vous pouvez utiliser Stream.CopyTo, mais sinon vous devrez copier le flux manuellement. This StackOverflow question a une bonne méthode pour les flux de copie:

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

Ainsi, votre code ressemblera à ceci:

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