2010-08-26 19 views
10

El siguiente código es bueno para subir archivos de texto, pero falla al descargar archivos JPEG (no del todo - el nombre del archivo es bueno, pero la imagen está dañada):Sube un archivo con codificación mediante FTP en C#

private void up(string sourceFile, string targetFile) 
{ 
    try 
    { 
     string ftpServerIP = ConfigurationManager.AppSettings["ftpIP"]; 
     string ftpUserID = ConfigurationManager.AppSettings["ftpUser"]; 
     string ftpPassword = ConfigurationManager.AppSettings["ftpPass"]; 

     //string ftpURI = ""; 
     string filename = "ftp://" + ftpServerIP + "//" + targetFile; 
     FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(filename); 
     ftpReq.Method = WebRequestMethods.Ftp.UploadFile; 
     ftpReq.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 

     StreamReader stream = new StreamReader(sourceFile); 
     Byte[] b = System.Text.Encoding.UTF8.GetBytes(stream.ReadToEnd()); 
     stream.Close(); 

     ftpReq.ContentLength = b.Length; 
     Stream s = ftpReq.GetRequestStream(); 
     s.Write(b, 0, b.Length); 
     s.Close(); 

     System.Net.FtpWebResponse ftpResp = (FtpWebResponse)ftpReq.GetResponse(); 
     MessageBox.Show(ftpResp.StatusDescription); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.ToString()); 
    } 
} 

tengo otra solución que puede cargar un archivo:

private void Upload(string sourceFile, string targetFile) 
{ 
    string ftpUserID; 
    string ftpPassword; 
    string ftpServerIP; 
    ftpServerIP = ConfigurationManager.AppSettings["ftpIP"]; 
    ftpUserID = ConfigurationManager.AppSettings["ftpUser"]; 
    ftpPassword = ConfigurationManager.AppSettings["ftpPass"]; 
    FileInfo fileInf = new FileInfo(sourceFile); 
    FtpWebRequest reqFTP; 

    // Create FtpWebRequest object from the Uri provided 
    reqFTP = (FtpWebRequest)(FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "//" + targetFile))); 

    // Provide the WebPermission Credintials 
    reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 

    // Bypass default lan settings 
    reqFTP.Proxy = null; 

    // By default KeepAlive is true, where the control connection is not closed 
    // after a command is executed. 
    reqFTP.KeepAlive = false; 

    // Specify the command to be executed. 
    reqFTP.Method = WebRequestMethods.Ftp.UploadFile; 

    // Specify the data transfer type. 
    reqFTP.UseBinary = true; 

    // Notify the server about the size of the uploaded file 
    reqFTP.ContentLength = fileInf.Length; 

    // The buffer size is set to 2kb 
    int buffLength = 2048; 
    Byte[] buff; 
    buff = new byte[buffLength]; 
    int contentLen; 

    // Opens a file stream (System.IO.FileStream) to read the file to be uploaded 
    FileStream fs = fileInf.OpenRead(); 

    try 
    { 
     // Stream to which the file to be upload is written 
     Stream strm = reqFTP.GetRequestStream(); 

     // Read from the file stream 2kb at a time 
     long filesize = fs.Length; 
     int i=0; 
     contentLen = fs.Read(buff, 0, buffLength); 

     // Till Stream content ends 
     while (contentLen != 0) 
     { 
      Application.DoEvents(); 
      // Write Content from the file stream to the FTP Upload Stream 
      strm.Write(buff, 0, contentLen); 
      contentLen = fs.Read(buff, 0, buffLength); 
      i = i + 1; 
      //Double percentComp = (i * buffLength) * 100/filesize; 
      //ProgressBar1.Value = (int)percentComp; 
     } 

     // Close the file stream and the Request Stream 
     strm.Close(); 
     fs.Close(); 
    } 

    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message, "Upload Error"); 
    } 
} 

pero aquí tengo el problema opuesto - la imagen es buena, pero el nombre del archivo está dañado.

Sé que es debido a la codificación, pero no saben cómo hacer que la matriz de bytes tiene la codificación deseada ...

+0

No puedo entender, ¿por qué tendría un problema con el nombre del archivo dañado con el segundo código, pero no con el primer código? Y por qué la respuesta aceptada ayuda con eso. En todos los casos, especifique el nombre del archivo exactamente de la misma manera. –

+0

Lo siento, Martin. Escribí la pregunta hace una década. No recuerdo cuál fue el problema y cuál fue la solución. Creo que deberías abrir un nuevo hilo con tu propia pregunta. – Asaf

+0

No tengo una pregunta, solo me pregunto cuál es el sentido de tu pregunta y la respuesta :) –

Respuesta

19

Pruebe este bit:

private static void up(string sourceFile, string targetFile) 
{    
    try 
    { 
     string ftpServerIP = ConfigurationManager.AppSettings["ftpIP"]; 
     string ftpUserID = ConfigurationManager.AppSettings["ftpUser"]; 
     string ftpPassword = ConfigurationManager.AppSettings["ftpPass"]; 
     ////string ftpURI = ""; 
     string filename = "ftp://" + ftpServerIP + "//" + targetFile; 
     FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(filename); 
     ftpReq.UseBinary = true; 
     ftpReq.Method = WebRequestMethods.Ftp.UploadFile; 
     ftpReq.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 

     byte[] b = File.ReadAllBytes(sourceFile); 

     ftpReq.ContentLength = b.Length; 
     using (Stream s = ftpReq.GetRequestStream()) 
     { 
      s.Write(b, 0, b.Length); 
     } 

     FtpWebResponse ftpResp = (FtpWebResponse)ftpReq.GetResponse(); 

     if (ftpResp != null) 
     { 
      MessageBox.Show(ftpResp.StatusDescription); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.ToString()); 
    } 
} 
+1

¿Por qué '' s.Write (b, 0, b.Length); 'dentro de un bloque' using'? –

+4

Porque 'Stream s' es un recurso' IDisposable'. –

+0

Aquí, la diferencia mágica también es 'byte [] b = File.ReadAllBytes (sourceFile);' compare con otros ejemplos encontrados alias 'Encoding.UTF8.GetBytes (stream.ReadToEnd())'. –

2

Debe utilizar un Stream para leer archivos binarios, no un StreamReader . StreamReader está diseñado para leer solo archivos de texto.

+0

Traté de jugar con el código durante 3 horas, y también encontré el streamReader que viene con la codificación (en el constructor); sin embargo, no pude entender cómo usar no el streamreader ni los objetos de transmisión. Las transmisiones son como una caja negra para mí :( – Asaf

2

En el primer ejemplo de código, habilite la transferencia binaria: FtpWebRequest.UseBinary = true. De lo contrario, convertirá lo que cree que son terminaciones de línea textuales entre las diversas convenciones de plataforma (pero en realidad son parte de la imagen).

+0

Debe haber algo más que falta ... Agregué la línea que me juegas, pero nada cambió. – Asaf

+0

Sí, ver la respuesta de Mark: estás intentando leer el archivo como texto UTF8 .Deshágase de ** StreamReader ** y lea los bytes directamente de la secuencia, p. con ** Stream.Read() **. –

0

System.Text.Encoding.UTF8.GetBytes(stream.ReadToEnd());

No haga esto a menos que el contenido de su corriente son de texto. Cambie su función para aceptar un parámetro booleano "binario", y utilice el último método de trabajo si ese indicador está configurado.

2

Su segundo fragmento lo hace de la manera correcta. Utiliza FileStream, no StreamReader. StreamReader solo es adecuado para archivos de texto.

Cuestiones relacionadas