2012-09-20 41 views
8

Próbuję pobrać plik, używając FtpWebRequest.Pobieranie plików za pomocą FtpWebRequest

private void DownloadFile(string userName, string password, string ftpSourceFilePath, string localDestinationFilePath) 
{ 
    int bytesRead = 0; 
    byte[] buffer = new byte[1024]; 

    FtpWebRequest request = CreateFtpWebRequest(ftpSourceFilePath, userName, password, true); 
    request.Method = WebRequestMethods.Ftp.DownloadFile; 

    Stream reader = request.GetResponse().GetResponseStream(); 
    BinaryWriter writer = new BinaryWriter(File.Open(localDestinationFilePath, FileMode.CreateNew)); 

    while (true) 
    { 
     bytesRead = reader.Read(buffer, 0, buffer.Length); 

     if (bytesRead == 0) 
      break; 

     writer.Write(buffer, 0, bytesRead); 
    }   
} 

wykorzystuje tę metodę CreateFtpWebRequest ja Utworzono:

private FtpWebRequest CreateFtpWebRequest(string ftpDirectoryPath, string userName, string password, bool keepAlive = false) 
{ 
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(ftpDirectoryPath)); 

    //Set proxy to null. Under current configuration if this option is not set then the proxy that is used will get an html response from the web content gateway (firewall monitoring system) 
    request.Proxy = null; 

    request.UsePassive = true; 
    request.UseBinary = true; 
    request.KeepAlive = keepAlive; 

    request.Credentials = new NetworkCredential(userName, password); 

    return request; 
} 

pobiera go. Ale informacje są zawsze uszkodzone. Ktoś wie, co się dzieje?

+0

Co masz na myśli przez "jest zawsze uszkodzony"? Proszę być bardziej konkretnym. – PVitt

+0

Chociaż miałem inny problem, komentarz opisu powyżej linii 'request.Proxy = null' funkcji CreateFtpWebRequest określał problem, który miałem. Dlatego przekaż! – UnTraDe

Odpowiedz

23

tylko zorientowaliśmy się:

private void DownloadFile(string userName, string password, string ftpSourceFilePath, string localDestinationFilePath) 
    { 
     int bytesRead = 0; 
     byte[] buffer = new byte[2048]; 

     FtpWebRequest request = CreateFtpWebRequest(ftpSourceFilePath, userName, password, true); 
     request.Method = WebRequestMethods.Ftp.DownloadFile; 

     Stream reader = request.GetResponse().GetResponseStream(); 
     FileStream fileStream = new FileStream(localDestinationFilePath, FileMode.Create); 

     while (true) 
     { 
      bytesRead = reader.Read(buffer, 0, buffer.Length); 

      if (bytesRead == 0) 
       break; 

      fileStream.Write(buffer, 0, bytesRead); 
     } 
     fileStream.Close();  
    } 

Gdyby użyć FileStream zamiast.

+0

Konieczność dodania "fileStream.Close();" po pętli while. W przeciwnym razie pobrany plik może zostać obcięty. – nanonerd

+0

Czy brakuje mi czegoś lub czy to rozwiązanie pozwala tylko pobierać pliki mniejsze niż 2kB? – Chrisi

+1

Bufor jest używany do przechowywania "kawałka" tego, co pobieramy. Te kawałki mają rozmiary 2kB. W pętli nadal czytamy fragmenty 2kB, dopóki ich nie ma. –

4

najbardziej trywialny sposób, aby pobrać plik z serwera FTP za pomocą ramy .NET używa WebClient.DownloadFile method:

WebClient client = new WebClient(); 
client.Credentials = new NetworkCredential("username", "password"); 
client.DownloadFile(
    "ftp://ftp.example.com/remote/path/file.zip", @"C:\local\path\file.zip"); 

Zastosowanie FtpWebRequest class, jeśli potrzebujesz większej kontroli tylko, że WebClient klasa nie oferuje (jak Szyfrowanie TLS/SSL, monitorowanie postępu itp.). Prostym sposobem jest po prostu skopiować strumień odpowiedzi FTP FileStream użyciu Stream.CopyTo metody:

FtpWebRequest request = 
    (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip"); 
request.Credentials = new NetworkCredential("username", "password"); 
request.Method = WebRequestMethods.Ftp.DownloadFile; 

using (Stream ftpStream = request.GetResponse().GetResponseStream()) 
using (Stream fileStream = File.Create(@"C:\local\path\file.zip")) 
{ 
    ftpStream.CopyTo(fileStream); 
} 

Tylko, jeśli trzeba monitorować postęp pobierania, trzeba skopiować zawartość przez kawałkami siebie:

FtpWebRequest request = 
    (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip"); 
request.Credentials = new NetworkCredential("username", "password"); 
request.Method = WebRequestMethods.Ftp.DownloadFile; 

using (Stream ftpStream = request.GetResponse().GetResponseStream()) 
using (Stream fileStream = File.Create(@"C:\local\path\file.zip")) 
{ 
    byte[] buffer = new byte[10240]; 
    int read; 
    while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     fileStream.Write(buffer, 0, read); 
     Console.WriteLine("Downloaded {0} bytes", fileStream.Position); 
    } 
} 

dla GUI toku (WinForms ProgressBar), patrz:
FtpWebRequest FTP download with ProgressBar

Jeśli chcesz ściągnąć wszystkie pliki z folderu zdalnego, zobacz
C# Download all files and subdirectories through FTP.

Powiązane problemy