Pregunta

Estoy usando el siguiente código para descargar un archivo desde un servidor FTP remoto:

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

El archivo que estoy descarga es un archivo DLL y mi problema es que está siendo alterado por este proceso de alguna manera. Lo sé porque el tamaño del archivo es cada vez mayor. Tengo la sospecha de que esta sección del código es la culpa:

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

puede ofrecer cualquier persona cualquier idea en cuanto a lo que puede estar mal?

¿Fue útil?

Solución

StreamReader y el trabajo StreamWriter con datos de caracteres, por lo que están decodificar el flujo de bytes a caracteres y luego codificarlo de nuevo a bytes de nuevo. Un archivo DLL contiene datos binarios, por lo que esta conversión de ida y vuelta introducirá errores. ¿Quieres leer bytes directamente desde el objeto responseStream y escritura a un FileStream que no está envuelto en una StreamWriter.

Si está utilizando .NET 4.0 se puede utilizar Stream.CopyTo , pero de lo contrario tendrá que copiar manualmente la corriente. Esta pregunta StackOverflow tiene un método adecuado para copiar corrientes :

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

Por lo tanto, el código se vería así:

using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (FileStream destination = File.Create(destinationFile))
{
    CopyStream(responseStream, destination);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top