2010-08-26 18 views
10

Il seguente codice è un bene per il caricamento dei file di testo, ma non riesce a caricare i file JPEG (non del tutto - il nome del file è buona, ma l'immagine è danneggiata):Carica un file con la codifica tramite FTP in 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()); 
    } 
} 

ho un'altra soluzione in grado di caricare un file:

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

ma qui ho il problema opposto - il quadro è buono, ma il nome del file è danneggiato.

so che è a causa della codifica, ma non so come fare l'array di byte hanno la codifica desiderato ...

+0

Non riesco a capire, perché dovresti avere problemi con il nome del file danneggiato con il secondo codice, ma non con il primo codice. E perché la risposta accettata sarebbe d'aiuto. In tutti i casi, si specifica il nome del file esattamente nello stesso modo. –

+0

Mi dispiace, Martin. Ho scritto la domanda un decennio fa. Non ricordo quale fosse il problema e quale fosse la soluzione. Penso che tu debba aprire una nuova discussione con la tua stessa domanda. – Asaf

+0

Non ho una domanda, mi chiedo solo qual è il punto della tua domanda e la risposta :) –

risposta

19

Prova questo 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

Perché 's.Write (b, 0, b.Length);' all'interno di un blocco 'using'? –

+4

Perché 'Stream s' è una risorsa' IDisposable'. –

+0

Qui, la differenza magica è anche 'byte [] b = File.ReadAllBytes (sourceFile);' confronta con altri esempi trovati alias 'Encoding.UTF8.GetBytes (stream.ReadToEnd())'. –

2

Si deve usare un Stream per leggere i file binario, non un StreamReader . StreamReader è progettato per leggere solo file di testo.

+0

Ho provato a giocare con il codice per 3 ore ora, e ho anche trovato lo streamReader che viene fornito con la codifica (in il costruttore) - ma non riuscivo a capire come usare non lo streamreader e gli oggetti del flusso. Gli stream sono come una scatola nera per me :( – Asaf

2

Nel primo esempio di codice, abilitare il trasferimento binario: FtpWebRequest.UseBinary = true. Altrimenti convertirà quelle che pensa siano finali di linee testuali tra le varie convenzioni della piattaforma (ma in realtà fanno parte dell'immagine).

+0

Ci deve essere qualcos'altro mancante ... Ho aggiunto la linea che mi giochi - ma nulla è cambiato – Asaf

+0

Sì, vedi la risposta di Mark: stai tentando di leggere il file come testo UTF8 .Elimina il ** StreamReader ** e leggi i byte direttamente dallo stream, ad es. con ** Stream.Read() **. –

0

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

Non fare questo a meno che il contenuto del vostro flusso sono testo. Cambia la tua funzione per accettare un parametro booleano "binario", e usa quest'ultimo, metodo di lavoro se questo flag è impostato.

2

Il secondo snippet fa nel modo giusto. Usa FileStream, non StreamReader. StreamReader è adatto solo per i file di testo.