2013-05-11 12 views
7

Sto provando a caricare un file zip sul server utilizzando C# (Framework 4) e il seguente è il mio codice.Il file zip viene danneggiato dopo il caricamento sul server utilizzando C#

string ftpUrl = ConfigurationManager.AppSettings["ftpAddress"]; 
string ftpUsername = ConfigurationManager.AppSettings["ftpUsername"]; 
string ftpPassword = ConfigurationManager.AppSettings["ftpPassword"]; 
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl + "Transactions.zip"); 
request.Proxy = new WebProxy(); //-----The requested FTP command is not supported when using HTTP proxy. 
request.Method = WebRequestMethods.Ftp.UploadFile; 
request.Credentials = new NetworkCredential(ftpUsername, ftpPassword); 
StreamReader sourceStream = new StreamReader(fileToBeUploaded); 
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd()); 
sourceStream.Close(); 
request.ContentLength = fileContents.Length; 
Stream requestStream = request.GetRequestStream(); 
requestStream.Write(fileContents, 0, fileContents.Length); 
requestStream.Close(); 
FtpWebResponse response = (FtpWebResponse)request.GetResponse(); 
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription); 
      response.Close(); 

Il file zip viene caricato con successo, ma quando ho provato ad aprire il file zip dal server (manualmente), mi ha mostrato Unexpected end of archive errore.
Per la compressione dei file sto usando Ionic.zip dll. Prima di trasferire il file zip, sono stato in grado di estrarre correttamente.

Qualsiasi aiuto apprezzato. Grazie.

+0

Cerca di evitare sourceStream.ReadToEnd() e copia i byte direttamente da sourceStream a requestStream –

risposta

14

Questo è il problema:

StreamReader sourceStream = new StreamReader(fileToBeUploaded); 
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd()); 

StreamReader (e qualsiasi TextReader) è per testo dati. Un file zip non è un testo.

Basta usare:

byte[] fileContents = File.ReadAllBytes(fileToBeUploaded); 

In questo modo non stiamo trattando i dati binari come testo, quindi non dovrebbe ottenere danneggiato.

Oppure, in alternativa, non caricare tutto in memoria separatamente - proprio flusso dei dati:

using (var requestStream = request.GetRequestStream()) 
{ 
    using (var input = File.OpenRead(fileToBeUploaded)) 
    { 
     input.CopyTo(requestStream); 
    } 
} 

noti inoltre che si dovrebbe utilizzare using dichiarazioni per tutti questi flussi, piuttosto che chiamare Close - in questo modo le risorse saranno disposte anche se viene lanciata un'eccezione.

+0

Mio Dio, ho ricevuto una risposta da Mr. Jon Skeet !!! Questo è un giorno fortunato per me. Grazie. – Praveen

+0

C'è un modo per sapere se il nostro file è stato caricato con successo o meno, come 'status.code = OK'? – Praveen

+1

@ user1671639: Sì: recupera il codice di stato da 'FtpWebResponse' e ​​verifica se è' CommandOK' o 'FileActionOK'. (Potrebbero essercene altri da cercare - sperimentatelo.) Mi aspetto che faccia un'eccezione quando si ottiene la risposta, se è fallita, ad essere onesti. –