Pergunta

I’m using the following code to download a file from a remote ftp server:

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

The file that I’m downloading is a dll and my problem is that it is being altered by this process in some way. I know this because the file size is increasing. I have a suspicion that this section of code is at fault:

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

Can anyone offer any ideas as to what may be wrong?

Foi útil?

Solução

StreamReader and StreamWriter work with character data, so you are decoding the stream from bytes to characters and then encoding it back to bytes again. A dll file contains binary data, so this round-trip conversion will introduce errors. You want to read bytes directly from the responseStream object and write to a FileStream that isn't wrapped in a StreamWriter.

If you are using .NET 4.0 you can use Stream.CopyTo, but otherwise you will have to copy the stream manually. This StackOverflow question has a good method for copying streams:

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

So, your code will look like this:

using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (FileStream destination = File.Create(destinationFile))
{
    CopyStream(responseStream, destination);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top