Upload and download a file to/from FTP server in C#/.NET

19,748

Upload

The most trivial way to upload a binary file to an FTP server using .NET framework is using WebClient.UploadFile:

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

If you need a greater control, that WebClient does not offer (like TLS/SSL encryption, ascii/text transfer mode, transfer resuming, etc), use FtpWebRequest. Easy way is to just copy a FileStream to FTP stream using Stream.CopyTo:

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

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

If you need to monitor an upload progress, you have to copy the contents by chunks yourself:

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

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

For GUI progress (WinForms ProgressBar), see:
How can we show progress bar for upload with FtpWebRequest

If you want to upload all files from a folder, see
Recursive upload to FTP server in C#.


Download

The most trivial way to download a binary file from an FTP server using .NET framework is using WebClient.DownloadFile:

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

If you need a greater control, that WebClient does not offer (like TLS/SSL encryption, ascii/text transfer mode, resuming transfers, etc), use FtpWebRequest. Easy way is to just copy an FTP response stream to FileStream using Stream.CopyTo:

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

If you need to monitor a download progress, you have to copy the contents by chunks yourself:

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

For GUI progress (WinForms ProgressBar), see:
FtpWebRequest FTP download with ProgressBar

If you want to download all files from a remote folder, see
C# Download all files and subdirectories through FTP.

Share:
19,748
jo phul
Author by

jo phul

Updated on June 24, 2022

Comments

  • jo phul
    jo phul almost 2 years

    I am using .NET 4 C#. I am trying to upload and then download a ZIP file to (my) server.

    For uploading I have

    using (WebClient client = new WebClient())
    {
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(MyUrl);
        request.Method = WebRequestMethods.Ftp.UploadFile;
        request.EnableSsl = false;
        request.Credentials = new NetworkCredential(MyLogin, MyPassword);
        byte[] fileContents = null;
        using (StreamReader sourceStream = new StreamReader(LocalFilePath))
        {
            fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
        }
        request.ContentLength = fileContents.Length;
        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(fileContents, 0, fileContents.Length);
        }
        FtpWebResponse response = null;
        response = (FtpWebResponse)request.GetResponse();
        response.Close();
    }
    

    This seems to work, in that I get a file on the server of the right size.

    1) How do I stream it, rather than load it into memory first? I will be uploading very large files.

    And for downloading I have

    using (WebClient client = new WebClient())
    {
        string HtmlResult = String.Empty;
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(remoteFile);
        request.Method = WebRequestMethods.Ftp.DownloadFile;
        request.EnableSsl = false;
        request.Credentials = new NetworkCredential(MyLogin, MyPassword);
        using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
        using (Stream responseStream = response.GetResponseStream())
        using (StreamReader reader = new StreamReader(responseStream))
        using (FileStream writer = new FileStream(localFilename, FileMode.Create))
        {
            long length = response.ContentLength;
            int bufferSize = 2048;
            int readCount;
            byte[] buffer = new byte[2048];
            readCount = responseStream.Read(buffer, 0, bufferSize);
            while (readCount > 0)
            {
                writer.Write(buffer, 0, readCount);
                readCount = responseStream.Read(buffer, 0, bufferSize);
            }
        }
    }
    

    2) Everything seems to work ... except when I try to unzip the downloaded ZIP file I get an invalid ZIP file.