2013-05-11 12 views
7

Próbuję przesłać plik zip na serwer przy użyciu C# (Framework 4), a następnie mój kod.Plik zip jest uszkodzony po przesłaniu na serwer przy użyciu 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(); 

Plik zip jest dodany pomyślnie, ale kiedy próbowałem otworzyć plik zip z serwera (manualnie), to pokazał mi Unexpected end of archive błąd.
Do kompresji plików używam Ionic.zip dll. Przed przeniesieniem pliku zip udało mi się wyodrębnić.

Każda pomoc doceniona. Dzięki.

+0

Staraj się unikać sourceStream.ReadToEnd() i skopiuj bajty bezpośrednio z sourceStream do requestStream –

Odpowiedz

14

To jest problem:

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

StreamReader (i każdy TextReader) jest dla tekstu danych. Plik zip nie jest tekstem.

Wystarczy użyć:

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

ten sposób nie traktujemy dane binarne jako tekst, więc nie powinno ulec uszkodzeniu.

Lub alternatywnie, nie ładuj to wszystko w pamięci oddzielnie - tylko strumień danych:

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

Należy również pamiętać, że należy używać using sprawozdań dla wszystkich tych strumieni, zamiast po prostu wywołanie Close - w ten sposób zasoby zostaną usunięte, nawet jeśli zostanie zgłoszony wyjątek.

+0

Mój Boże, dostałem odpowiedź od pana Jona Skeeta !!! To dla mnie szczęśliwy dzień. Dzięki. – Praveen

+0

Czy istnieje sposób sprawdzenia, czy nasz plik został przesłany pomyślnie, czy nie, np. "Status.code = OK"? – Praveen

+1

@ user1671639: Tak - pobierz kod statusu z 'FtpWebResponse' i zobacz, czy jest to' CommandOK' lub 'FileActionOK'. (Mogą być inni, których należy szukać - poeksperymentuj z tym). Spodziewałbym się, że wyrzuci wyjątek, gdy otrzymasz odpowiedź, jeśli nie, szczerze mówiąc. –

Powiązane problemy