Web Design that taps into the haromny and vision of your dreams.

Ultimate Guide to FTP using C#

Ultimate Guide to FTP using C#

Written By on in C#

1,459 words, estimated reading time 7 minutes.

How to use the FtpWebRequest and FtpWebResponse classes to create a FTP utility class which will allow us to retrieve a directory listing, download files, upload files and delete files.

I'm going to create a utility class during this tutorial which contains a series of methods to perform using FTP. You can copy and paste into your project, or adapt to suit your needs.

I'm basing this on a console application with an extra class file called FTPUtility.cs. All this code goes inside that file.

The first thing I have done is create a set of private fields that need to be populated from the constructor.

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
 
namespace Utils
{
    public class FTPClient
    {
        // The hostname or IP address of the FTP server
        private string _remoteHost;
 
        // The remote username
        private string _remoteUser;
 
        // Password for the remote user
        private string _remotePass;
    }
}

The constructor for this class takes in the connection properties for the remote host.

public FTPClient(string remoteHost, string remoteUser, string remotePassword)
{
    _remoteHost = remoteHost;
    _remoteUser = remoteUser;
    _remotePass = remotePassword;
}

Directory Listings

The first thing we are going to look at is establishing a connection to the server and retrieving a file list.

public List<string> DirectoryListing()
{
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost);
    request.Method = WebRequestMethods.Ftp.ListDirectory;
    request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
    Stream responseStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(responseStream);
 
    List<string> result = new List<string>();
 
    while (!reader.EndOfStream)
    {
        result.Add(reader.ReadLine());
    }
 
    reader.Close();
    response.Close();
    return result;
}

If I run this over my test site with the following code:

namespace FTPTestApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            Utils.FTPClient client = new Utils.FTPClient("ftp://localhost", "ftpUser", "ftpPass");
            List<string> files = client.DirectoryListing();
            foreach (string s in files)
            {
                Console.WriteLine(s);
            }
            Console.ReadLine();
        }
    }
}

The result is:

.cshrc
.imap
.login
.login_conf
.mail_aliases
.mailrc
.profile
.rhosts
.shrc
backup
boxes
log_config
public_html
www_logs

Now the next logical step is to navigate to a folder, this can be done by amending the parameter to the WebRequest.Create method. I have created an overloaded method so that we can browse the root or into a given folder.

public List<string> DirectoryListing()
{
    return DirectoryListing(string.Empty);
}
 
public List<string> DirectoryListing(string folder)
{
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + folder);
    request.Method = WebRequestMethods.Ftp.ListDirectory;
    request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
    Stream responseStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(responseStream);
 
    List<string> result = new List<string>();
 
    while (!reader.EndOfStream)
    {
        result.Add(reader.ReadLine());
    }
 
    reader.Close();
    response.Close();
    return result;
}

I can now add directory information to the original call to look inside a folder.

Utils.FTPClient client = new Utils.FTPClient("ftp://localhost/public_html/", "ftpUser", "ftpPass");

Downloading a File

The next task is to download a file from the server to our PC. This is done in much the same way as directory listings.

public void Download(string file, string destination)
{
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + file);
    request.Method = WebRequestMethods.Ftp.DownloadFile;
    request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
    Stream responseStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(responseStream);
 
    StreamWriter writer = new StreamWriter(destination);
    writer.Write(reader.ReadToEnd());
 
    writer.Close();
    reader.Close();
    response.Close();
}

To call this method use:

Utils.FTPClient client = new Utils.FTPClient("ftp://localhost/public_html/", "ftpUser", "ftpPass");
client.Download("test.zip", "c:test.zip");

Hopefully you can start to see a pattern forming when using FtpWebRequest methods. In fact, all the code is pretty similar regardless of what action you are performing. The WebRequestMethods.Ftp enum contains a list of actions you can perform. These include:

  • AppendFile - Append a file to an existing file on an FTP server (FTP APPE)
  • DeleteFile - Delete a file on an FTP server (FTP DELE)
  • DownloadFile - Download a file from an FTP server (FTP RETR)
  • GetFileSize - Retrieve the size of a file on an FTP server (FTP SIZE)
  • ListDirectory - Gets a short listing of the files on an FTP server (FTP NLIST)
  • ListDirectoryDetails - Gets a detailed listing of the files on an FTP server (FTP LIST)
  • MakeDirectory - Creates a directory on an FTP server (FTP MKD)
  • RemoveDirectory - Method that removes a directory (FTP RM)
  • Rename - Renames a directory (FTP RENAME)
  • UploadFile - Uploads a file to an FTP server (FTP STOR)
  • UploadFileWithUniqueName - Uploads a file with a unique name to an FTP server (FTP STOU)

Uploading a File through FTP

The final example I am going to show is how to upload a file to the server. This method differs slightly as we need to create a StreamReader to read the source file.

public void UploadFile(string FullPathFilename)
{
    string filename = Path.GetFileName(FullPathFilename);
 
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + filename);
    request.Method = WebRequestMethods.Ftp.UploadFile;
    request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
 
    StreamReader sourceStream = new StreamReader(FullPathFilename);
    byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
 
    request.ContentLength = fileContents.Length;
 
    Stream requestStream = request.GetRequestStream();
    requestStream.Write(fileContents, 0, fileContents.Length);
 
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
 
    response.Close();
    requestStream.Close();
    sourceStream.Close();
}

And that's all there is to it.

Just a few points to remember:

  • WebRequest.Create takes the full URL including path and file name. To work with a file specify the full path name e.g. ftp://localhost/folder/test/myfile.zip.
  • To work with a folder/directory, specify the full path e.g. ftp://localhost/folder/test/
  • You cannot upload a file to ftp://localhost/folder/test/, you have to specify the filename when you create the WebRequest.

Code in Full

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
 
namespace Utils
{
    public class FTPClient
    {
        // The hostname or IP address of the FTP server
        private string _remoteHost;
 
        // The remote username
        private string _remoteUser;
 
        // Password for the remote user
        private string _remotePass;
 
        public FTPClient(string remoteHost, string remoteUser, string remotePassword, bool debug)
        {
            _remoteHost = remoteHost;
            _remoteUser = remoteUser;
            _remotePass = remotePassword;
        }
 
        /// <summary>
        /// Get a list of files and folders on the FTP server
        /// </summary>
        /// <returns></returns>
        public List<string> DirectoryListing()
        {
            return DirectoryListing(string.Empty);
        }
 
        /// <summary>
        /// List files and folders in a given folder on the server
        /// </summary>
        /// <param name="folder"></param>
        /// <returns></returns>
        public List<string> DirectoryListing(string folder)
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + folder);
            request.Method = WebRequestMethods.Ftp.ListDirectory;
            request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
 
            List<string> result = new List<string>();
 
            while (!reader.EndOfStream)
            {
                result.Add(reader.ReadLine());
            }
 
            reader.Close();
            response.Close();
            return result;
        }
 
        /// <summary>
        /// Download a file from the FTP server to the destination
        /// </summary>
        /// <param name="filename">filename and path to the file, e.g. public_html/test.zip</param>
        /// <param name="destination">The location to save the file, e.g. c:test.zip</param>
        public void Download(string filename, string destination)
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + filename);
            request.Method = WebRequestMethods.Ftp.DownloadFile;
            request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
 
            StreamWriter writer = new StreamWriter(destination);
            writer.Write(reader.ReadToEnd());
 
            writer.Close();
            reader.Close();
            response.Close();
        }
 
        /// <summary>
        /// Remove a file from the server.
        /// </summary>
        /// <param name="filename">filename and path to the file, e.g. public_html/test.zip</param>
        public void DeleteFileFromServer(string filename)
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + filename);
            request.Method = WebRequestMethods.Ftp.DeleteFile;
            request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            response.Close();
        }
 
        /// <summary>
        /// Upload a file to the server
        /// </summary>
        /// <param name="source">Full path to the source file e.g. c:test.zip</param>
        /// <param name="destination">destination folder and filename e.g. public_html/test.zip</param>
        public void UploadFile(string source, string destination)
        {
            string filename = Path.GetFileName(source);
 
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + destination);
            request.Method = WebRequestMethods.Ftp.UploadFile;
            request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
 
            StreamReader sourceStream = new StreamReader(source);
            byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
 
            request.ContentLength = fileContents.Length;
 
            Stream requestStream = request.GetRequestStream();
            requestStream.Write(fileContents, 0, fileContents.Length);
 
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
 
            response.Close();
            requestStream.Close();
            sourceStream.Close();
        }
    }
}

Last updated on: Wednesday 21st June 2017

 

Comments
Wasae

Wasae

Getting This Exception While Uploading File on this Line Request.GetRequestStream() "The remote server returned an error: (500) Syntax error, command unrecognized"

Reply to Wasae
Vladislav

Vladislav

As I see there is no check for file consistancy on ftp.

I mean next case. If some1 is uploading a big file on ftp and at this moment you start downloading it.
This will cause you won't receive full file.

Reply to Vladislav
moses

moses

I have a case to abort an ftpwebrequest download at any time during download operation. The process is synch and I am using (FtpWebResponse)ftpRequest.GetResponse() so I cannot use Ftpwebrequest.Abort();

Reply to moses
James Dennis

James Dennis

Please note that this will not work on compressed files. See http://stackoverflow.com/questions/16495735/zip-file-is-getting-corrupted-after-uploaded-to-server-using-c-sharp. Otherwise, thank you for your contribution. It was very helpful!

Reply to James Dennis
Santiago

Santiago

Thanks a lot, I'm building a project which involves ftp, and you just taught me the basics. Greets

Reply to Santiago
Santiago

Santiago

Thanks a lot, I'm building a project which involves ftp, and you just taught me the basics. Greets

Reply to Santiago

 

Leave a Reply

Your email address will not be published.





If you find something abusive or that does not comply with our terms or guidelines please flag it as inappropriate.

Copyright © 2001-2018 Tim Trott, all rights reserved. Web Design by Azulia Designs

This web page is licensed for your personal, private, non-commercial use only.

Disclaimer, Privacy & LegalSitemapContact Me