FtpClient Class

System.Net.FtpClient

Collapse image Expand Image Copy image CopyHover image
FTP Control Connection. Speaks the FTP protocol with the server and provides facilities for performing basic transactions. Debugging problems with FTP transactions is much easier to do when you can see exactly what is sent to the server and the reply System.Net.FtpClient gets in return. Please review the Debug example below for information on how to add TraceListeners for capturing the convorsation between System.Net.FtpClient and the server.

Namespace: System.Net.FtpClient
Assembly: System.Net.FtpClient (in System.Net.FtpClient.dll) Version: 1.0.5064.17461

Syntax

C#
public class FtpClient : IDisposable, IFtpClient
Visual Basic
Public Class FtpClient
	Implements IDisposable, IFtpClient
Visual C++
public ref class FtpClient : IDisposable, 
	IFtpClient

Examples

The following example illustrates how to assist in debugging System.Net.FtpClient by getting a transaction log from the server.
C# Copy imageCopy
using System;
using System.Diagnostics;
using System.Net.FtpClient;

namespace Examples {
    /// <summary>
    /// Example for logging server transactions for use in debugging problems. If DEBUG
    /// is defined this information is logged via System.Diagnostics.Debug.Write() as well 
    /// so you'll the same information in your Visual Studio Output window
    /// </summary>
    public static class DebugExample {
        /// <summary>
        /// Log to a console window
        /// </summary>
        static void LogToConsole() {
            FtpTrace.AddListener(new ConsoleTraceListener());

            // now use System.Net.FtpCLient as usual and the server transactions
            // will be written to the Console window.
        }

        /// <summary>
        /// Log to a text file
        /// </summary>
        static void LogToFile() {
            FtpTrace.AddListener(new TextWriterTraceListener("log_file.txt"));

            // now use System.Net.FtpCLient as usual and the server transactions
            // will be written to the specified log file.
        }

        /// <summary>
        /// Custom trace listener class that can log the transaction
        /// however you want.
        /// </summary>
        class CustomTraceListener : TraceListener {
            public override void Write(string message) {
                Console.Write(message);
            }

            public override void WriteLine(string message) {
                Console.WriteLine(message);
            }
        }

        /// <summary>
        /// Log to a custom TraceListener
        /// </summary>
        static void LogToCustomListener() {
            FtpTrace.AddListener(new CustomTraceListener());
        }
    }
}

Examples

The following example demonstrates adding a custom file listing parser in the event that you encounter a list format not already supported.
C# Copy imageCopy
using System;
using System.Text.RegularExpressions;
using System.Net.FtpClient;
using System.Globalization;

namespace Examples {
    /// <summary>
    /// This is an example a FTP file listing parser. This code in the example
    /// is currently used to parse UNIX style long listings and serves as an
    /// example for adding your own parser.
    /// </summary>
    class CustomParser {
        /// <summary>
        /// Adds a custom file listing parser
        /// </summary>
        public static void AddCustomParser() {
            FtpListItem.AddParser(new FtpListItem.Parser(ParseUnixList));
        }

        /// <summary>
        /// Parses LIST format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        static FtpListItem ParseUnixList(string buf, FtpCapability capabilities) {
            FtpListItem item = new FtpListItem();
            Match m = null;
            string regex =
                @"(?<permissions>[\w-]{10})\s+" +
                @"(?<objectcount>\d+)\s+" +
                @"(?<user>[\w\d]+)\s+" +
                @"(?<group>[\w\d]+)\s+" +
                @"(?<size>\d+)\s+" +
                @"(?<modify>\w+\s+\d+\s+\d+:\d+|\w+\s+\d+\s+\d+)\s+" +
                @"(?<name>.*)$";

            if (!(m = Regex.Match(buf, regex, RegexOptions.IgnoreCase)).Success)
                return null;

            if (m.Groups["permissions"].Value.StartsWith("d"))
                item.Type = FtpFileSystemObjectType.Directory;
            else if (m.Groups["permissions"].Value.StartsWith("-"))
                item.Type = FtpFileSystemObjectType.File;
            else
                return null;

            // if we can't determine a file name then
            // we are not considering this a successful parsing operation.
            if (m.Groups["name"].Value.Length < 1)
                return null;
            item.Name = m.Groups["name"].Value;

            if (item.Type == FtpFileSystemObjectType.Directory && (item.Name == "." || item.Name == ".."))
                return null;

            ////
            // Ignore the Modify times sent in LIST format for files
            // when the server has support for the MDTM command
            // because they will never be as accurate as what can be had 
            // by using the MDTM command. MDTM does not work on directories
            // so if a modify time was parsed from the listing we will try
            // to convert it to a DateTime object and use it for directories.
            ////
            if ((!capabilities.HasFlag(FtpCapability.MDTM) || item.Type == FtpFileSystemObjectType.Directory) && m.Groups["modify"].Value.Length > 0)
                item.Modified = m.Groups["modify"].Value.GetFtpDate(DateTimeStyles.AssumeUniversal);

            if (m.Groups["size"].Value.Length > 0) {
                long size;

                if (long.TryParse(m.Groups["size"].Value, out size))
                    item.Size = size;
            }

            if (m.Groups["permissions"].Value.Length > 0) {
                Match perms = Regex.Match(m.Groups["permissions"].Value,
                    @"[\w-]{1}(?<owner>[\w-]{3})(?<group>[\w-]{3})(?<others>[\w-]{3})",
                    RegexOptions.IgnoreCase);

                if (perms.Success) {
                    if (perms.Groups["owner"].Value.Length == 3) {
                        if (perms.Groups["owner"].Value[0] == 'r')
                            item.OwnerPermissions |= FtpPermission.Read;
                        if (perms.Groups["owner"].Value[1] == 'w')
                            item.OwnerPermissions |= FtpPermission.Write;
                        if (perms.Groups["owner"].Value[2] == 'x' || perms.Groups["owner"].Value[2] == 's')
                            item.OwnerPermissions |= FtpPermission.Execute;
                        if (perms.Groups["owner"].Value[2] == 's' || perms.Groups["owner"].Value[2] == 'S')
                            item.SpecialPermissions |= FtpSpecialPermissions.SetUserID;
                    }

                    if (perms.Groups["group"].Value.Length == 3) {
                        if (perms.Groups["group"].Value[0] == 'r')
                            item.GroupPermissions |= FtpPermission.Read;
                        if (perms.Groups["group"].Value[1] == 'w')
                            item.GroupPermissions |= FtpPermission.Write;
                        if (perms.Groups["group"].Value[2] == 'x' || perms.Groups["group"].Value[2] == 's')
                            item.GroupPermissions |= FtpPermission.Execute;
                        if (perms.Groups["group"].Value[2] == 's' || perms.Groups["group"].Value[2] == 'S')
                            item.SpecialPermissions |= FtpSpecialPermissions.SetGroupID;
                    }

                    if (perms.Groups["others"].Value.Length == 3) {
                        if (perms.Groups["others"].Value[0] == 'r')
                            item.OthersPermissions |= FtpPermission.Read;
                        if (perms.Groups["others"].Value[1] == 'w')
                            item.OthersPermissions |= FtpPermission.Write;
                        if (perms.Groups["others"].Value[2] == 'x' || perms.Groups["others"].Value[2] == 't')
                            item.OthersPermissions |= FtpPermission.Execute;
                        if (perms.Groups["others"].Value[2] == 't' || perms.Groups["others"].Value[2] == 'T')
                            item.SpecialPermissions |= FtpSpecialPermissions.Sticky;
                    }
                }
            }

            return item;
        }
    }
}

Examples

The following example demonstrates how to validate a SSL certificate when using SSL/TLS.
C# Copy imageCopy
using System;
using System.Net;
using System.Net.FtpClient;

namespace Examples {
    public static class ValidateCertificateExample {
        public static void ValidateCertificate() {
            using (FtpClient conn = new FtpClient()) {
                conn.Host = "localhost";
                conn.Credentials = new NetworkCredential("ftptest", "ftptest");
                conn.EncryptionMode = FtpEncryptionMode.Explicit;
                conn.ValidateCertificate += new FtpSslValidation(OnValidateCertificate);
                conn.Connect();
            }
        }

        static void OnValidateCertificate(FtpClient control, FtpSslValidationEventArgs e) {
            if (e.PolicyErrors != System.Net.Security.SslPolicyErrors.None) {
                // invalid cert, do you want to accept it?
                // e.Accept = true;
            }
        }
    }
}

Examples

The following example demonsrates how to download a file.
C# Copy imageCopy
using System;
using System.IO;
using System.Net;
using System.Net.FtpClient;

namespace Examples {
    public class OpenReadExample {
        public static void OpenRead() {
            using(FtpClient conn = new FtpClient()) {
                conn.Host = "localhost";
                conn.Credentials = new NetworkCredential("ftptest", "ftptest");

                using(Stream istream = conn.OpenRead("/full/or/relative/path/to/file")) {
                    try {
                        // istream.Position is incremented accordingly to the reads you perform
                        // istream.Length == file size if the server supports getting the file size
                        // also note that file size for the same file can vary between ASCII and Binary
                        // modes and some servers won't even give a file size for ASCII files! It is
                        // recommended that you stick with Binary and worry about character encodings
                        // on your end of the connection.
                    }
                    finally {
                        Console.WriteLine();
                        istream.Close();
                    }
                }
            }
        }
    }
}

Examples

The following example demonstrates how to download a file using a URI object.
C# Copy imageCopy
using System;
using System.IO;
using System.Net.FtpClient;

namespace Examples {
    public static class OpenReadURI {
        public static void OpenURI() {
            using (Stream s = FtpClient.OpenRead(new Uri("ftp://server/path/file"))) {
                byte[] buf = new byte[8192];
                int read = 0;

                try {
                    while ((read = s.Read(buf, 0, buf.Length)) > 0) {
                        Console.Write("\r{0}/{1} {2:p}     ",
                            s.Position, s.Length,
                            ((double)s.Position / (double)s.Length));
                    }
                }
                finally {
                    Console.WriteLine();
                    s.Close();
                }
            }
        }
    }
}

Examples

The following example demonstrates how to upload a file.
C# Copy imageCopy
using System;
using System.IO;
using System.Net;
using System.Net.FtpClient;

namespace Examples {
    public class OpenWriteExample {
        public static void OpenWrite() {
            using (FtpClient conn = new FtpClient()) {
                conn.Host = "localhost";
                conn.Credentials = new NetworkCredential("ftptest", "ftptest");

                using (Stream ostream = conn.OpenWrite("/full/or/relative/path/to/file")) {
                    try {
                        // istream.Position is incremented accordingly to the writes you perform
                    }
                    finally {
                        ostream.Close();
                    }
                }
            }
        }
    }
}

Examples

The following example demonstrates how to upload a file using a URI object.
C# Copy imageCopy
using System;
using System.IO;
using System.Net.FtpClient;

namespace Examples {
    static class OpenWriteURI {
        public static void OpenURI() {
            using (Stream s = FtpClient.OpenWrite(new Uri("ftp://server/path/file"))) {
                try {
                    // write data to the file on the server
                }
                finally {
                    s.Close();
                }
            }
        }
    }
}

Examples

The following example demonstrates how to append to a file.
C# Copy imageCopy
using System;
using System.IO;
using System.Net;
using System.Net.FtpClient;

namespace Examples {
    public class OpenAppendExample {
        public static void OpenAppend() {
            using (FtpClient conn = new FtpClient()) {
                conn.Host = "localhost";
                conn.Credentials = new NetworkCredential("ftptest", "ftptest");

                using (Stream ostream = conn.OpenAppend("/full/or/relative/path/to/file")) {
                    try {
                        // be sure to seek your output stream to the appropriate location, i.e., istream.Position
                        // istream.Position is incremented accordingly to the writes you perform
                        // istream.Position == file size if the server supports getting the file size
                        // also note that file size for the same file can vary between ASCII and Binary
                        // modes and some servers won't even give a file size for ASCII files! It is
                        // recommended that you stick with Binary and worry about character encodings
                        // on your end of the connection.
                    }
                    finally {
                        ostream.Close();
                    }
                }
            }
        }
    }
}

Examples

The following example demonstrates how to append to a file using a URI object.
C# Copy imageCopy
using System;
using System.IO;
using System.Net.FtpClient;

namespace Examples {
    class OpenAppendURI {
        public static void OpenURI() {
            using (Stream s = FtpClient.OpenAppend(new Uri("ftp://server/path/file"))) {
                try {
                    // write data to the file on the server
                }
                finally {
                    s.Close();
                }
            }
        }
    }
}

Examples

The following example demonstrates how to get a file listing from the server.
C# Copy imageCopy
using System;
using System.Net;
using System.Net.FtpClient;

namespace Examples {
    static class GetListingExample {
        public static void GetListing() {
            using (FtpClient conn = new FtpClient()) {
                conn.Host = "localhost";
                conn.Credentials = new NetworkCredential("ftptest", "ftptest");

                foreach (FtpListItem item in conn.GetListing(conn.GetWorkingDirectory(),
                    FtpListOption.Modify | FtpListOption.Size)) {

                    switch (item.Type) {
                        case FtpFileSystemObjectType.Directory:
                            break;
                        case FtpFileSystemObjectType.File:
                            break;
                        case FtpFileSystemObjectType.Link:
                            // derefernece symbolic links
                            if (item.LinkTarget != null) {
                                // see the DereferenceLink() example
                                // for more details about resolving links.
                                item.LinkObject = conn.DereferenceLink(item);

                                if (item.LinkObject != null) {
                                    // switch (item.LinkObject.Type)...
                                }
                            }
                            break;
                    }
                }

                // same example except automatically dereference symbolic links.
                // see the DereferenceLink() example for more details about resolving links.
                foreach (FtpListItem item in conn.GetListing(conn.GetWorkingDirectory(),
                    FtpListOption.Modify | FtpListOption.Size | FtpListOption.DerefLinks)) {

                    switch (item.Type) {
                        case FtpFileSystemObjectType.Directory:
                            break;
                        case FtpFileSystemObjectType.File:
                            break;
                        case FtpFileSystemObjectType.Link:
                            if (item.LinkObject != null) {
                                // switch (item.LinkObject.Type)...
                            }
                            break;
                    }
                }
            }
        }
    }
}

Inheritance Hierarchy

System..::..Object
  System.Net.FtpClient..::..FtpClient

See Also