Revision: 37187
                            
                                                            
                                    
                                        
Updated Code
                                    
                                    
                                                    
                        at January 6, 2011 13:25 by kyrathaba
                            
                            Updated Code
namespace Kyrathasoft.NetUtilities.FTPclient {
    //developed this class on Saturday, 01/01/2011
    //added method DirectoryDetails() on 01/02/2011
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Text;
    using Kyrathasoft.Dialogs.ErrLogging;
    public class clsFTPclient {
        public string NL = Environment.NewLine;
        /* 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.         
         * 
         * 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)
         * 
         */
        #region clsFTPclient_PrivateMembers
        // 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;
        #endregion
        #region clsFTPclient_Constructors
        //constructor
        public clsFTPclient(string remoteHost, string remoteUser, 
            string remotePassword) {
            _remoteHost = remoteHost;
            _remoteUser = remoteUser;
            _remotePass = remotePassword;           
        }
        #endregion
        #region clsFTPclient_Methods
        public List<clsDirDetails> DirectoryDetails(string subdirectory) {
            List<clsDirDetails> the_details = new List<clsDirDetails>();
            clsDirDetails details;
            // Get the object used to communicate with the server.
            FtpWebRequest request = 
                (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            request.Credentials = 
                new NetworkCredential(_remoteUser, _remotePass);
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            while (!reader.EndOfStream) {
                details = new clsDirDetails();
                //once .Unparsed is set, clsDirDetails internally calcs 
                //and assigns DirMemberType, LastModified and PathOrFilename
                //These assignments are made just as soon as the .Unparsed
                //property is set, BEFORE details are added to the List
                details.Unparsed = reader.ReadLine();               
                the_details.Add(details);
            }
            return the_details;
        }
        public List<string> DirectoryListing(string subdirectory) {
            /* Examples of how to invoke:
             * 
             * 
             * 
             * 
             * sample button click_event handler follows...
             * =============================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            //gives root directory listing
            List<string> files = client.DirectoryListing(""); 
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + NL;
            }
             * ============================================================
             * 
             * 
             * 
                                        ................
             * 
             * 
             * 
             * another sample button click_event handler follows...
             * ===========================+================================
            string username = "my_username";
            string password = "my_password";
            string host = "ftp://mywebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            //lists the /httpdocs/non_church subdirectory
            List<string> files = client.DirectoryListing("//httpdocs//non_church");
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + NL;
            }
             * ============================================================ */
             
            List<string> result = new List<string>();
            try {
                FtpWebRequest request = 
                    (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
                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);                
                while (!reader.EndOfStream) {
                    result.Add(reader.ReadLine());
                }
                reader.Close();
                response.Close();
                return result;
            }
            catch (Exception ex) {
                clsErrLog errLog = new clsErrLog("Error in clsFTPclient.DirectoryListing():" +                                    NL + ex.Message);                
                return result;
            }
        }
        public void DownloadFile(string file, string destination) {
            /* Examples of how to invoke:
             * 
             *              * sample button click_event handler follows...
             * ======================================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host + "/httpdocs/downloads/", username, password);
            client.DownloadFile("booksOnServer.html", "downloadedToLocalDirectory.html");
            }
             * ===================================================================== */
             
            if (FileExistsAtThisURI(_remoteHost + file, _remoteUser, 
                _remotePass)) {
                try {
                    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();
                }
                catch (Exception ex) {
                    clsErrLog errLogger = 
                        new clsErrLog("Error in clsFTPclient.DownloadFile()" +                                                                      NL + ex.Message);                    
                }
            }
            else {
                clsErrLog errLogger = 
                    new clsErrLog("Error in clsFTPclient.DownloadFile(): " +                                                                NL + "The file you're attempting to download, '" + 
                    (_remoteHost + file) +
                    "', doesn't exist on the server at the URI you specified when " +
                    "you invoked the Download method.");
            }
        }
        public bool FileExistsAtThisURI(string fullFtpFilepath, string userName, 
            string passWord) {
            bool exists = true;
            var request = 
                (FtpWebRequest)WebRequest.Create(fullFtpFilepath);
            request.Credentials = 
                new NetworkCredential(userName, passWord);
            request.Method = 
                WebRequestMethods.Ftp.GetDateTimestamp;
            try {
                FtpWebResponse response = 
                    (FtpWebResponse)request.GetResponse();
            }
            catch (WebException ex) {
                FtpWebResponse response = (FtpWebResponse)ex.Response;
                if (response.StatusCode ==
                    FtpStatusCode.ActionNotTakenFileUnavailable) {
                    exists = false; //Does not exist
                }
            }
            return exists;
        }
        public void UploadFile(string FullPathFilename) {
            /* Be sure to invoke UploadFile on an asynch thread, 
             * like on a backgroundWorker...
             
            private void backgroundWorker1_DoWork(object sender, 
             * System.ComponentModel.DoWorkEventArgs e) {
            
                string username = "my_username";
                string password = "my_password";
                string host = "ftp://mywebsite.com";
                string myLocal = Path.GetDirectoryName(Application.ExecutablePath) + 
                   "\\myTextFile.txt";
                string myRemote = host + "/httpdocs/non_church/";        
                clsFTPclient client = new clsFTPclient(myRemote, username, password);            
                client.UploadFile(myLocal);
            }
             * 
             *                     ... or, rather than use a backgroundWorker...
             *                     
             * set up the same variables as above (username, password, host, myLocal, myRemote)
             * 
             * instantiate client as shown above, and then....
             * 
             * new System.Threading.Thread(() => 
             *      client.UploadFile(Path.GetDirectoryName(Application.ExecutablePath) + 
                    "\\myTextFile.txt")).Start(); */
            string filename = Path.GetFileName(FullPathFilename);
            try {
                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();
            }
            catch (Exception ex) {
                clsErrLog errLogger = 
                    new clsErrLog("Error in clsFTPclient.UploadFile()" + 
                    NL + ex.Message);                
            }            
        }
        #endregion
        //next right-brace ends clsFTPclient
    }    
    public class clsDirDetails {
        //a class to hold, in a convenient way, the details that are returned
        //by WebRequestMethods.Ftp.ListDirectoryDetails
        public enum DirectoryDetail { IsFileInDir, IsSubdirInDir };
        #region clsDirDetails_PrivateMembers
        private DirectoryDetail dirMemberType; //is it a file or subdirectory?
        private string pathOrFilename; //path of subdir or filename if it's a file
        private string lastModified; //last time file got modified (applies to files only)
        private string unparsed; //the unparsed line that contains details
        private string ownerPermissions; //usually this will be rwx (read/write/execute)
        private bool ownerCanRead; //owner CAN or CANNOT read the specified dir/file
        private bool ownerCanWrite; //same as above, except WRITE rather than READ
        private bool ownerCanExecute; //same as above, except EXECUTE rather than WRITE
        #endregion
        #region clsDirDetails_Properties
        //is it a file or a subdirectory?
        public DirectoryDetail DirMemberType {
            get { return dirMemberType; }
            set { dirMemberType = value; }
        }
        //owner permissions
        public string OwnerPermissions {
            get { return ownerPermissions; }
            set { ownerPermissions = value; }
        }
        //owner can read?
        public bool OwnerCanRead {
            get { return ownerCanRead; }
            set { ownerCanRead = value; }
        }
        //owner can write?
        public bool OwnerCanWrite {
            get { return ownerCanWrite; }
            set { ownerCanWrite = value; }
        }
        //owner can execute?
        public bool OwnerCanExecute {
            get { return OwnerCanExecute; }
            set { ownerCanExecute = value; }
        }
        //the full path
        public string PathOrFilename {
            get { return pathOrFilename; }
            set { pathOrFilename = value; }
        }
        //for files only...
        public string LastModified {
            get { return lastModified; }
            set { lastModified = value; }
        }
        //the unparsed line that contains details
        public string Unparsed {
            get { return unparsed; }
            set {
                unparsed = value;
                LastModified = getDateTimeString(unparsed);
                //also parse out the subdir path or filename                
                PathOrFilename = getPathOrFilename(unparsed);
                //assign DirMemberType
                DirMemberType = getDirectoryDetail(unparsed);
                //assign OwnerPermissions
                ownerPermissions = unparsed.Substring(1, 3);
                if (ownerPermissions.Contains("r")) { 
                    ownerCanRead = true; } 
                else { ownerCanRead = false; }
                if (ownerPermissions.Contains("w")) { 
                    ownerCanWrite = true; } 
                else { ownerCanWrite = false; }
                if (ownerPermissions.Contains("x")) { 
                    ownerCanExecute = true; } 
                else { ownerCanExecute = false; }
                //next right-brace ends set accessor of Unparsed property
            }
            //next right-brace ends Property Unparsed
        }
        #endregion
        #region clsDirDetails_Methods
        clsDirDetails.DirectoryDetail getDirectoryDetail(string unparsedInfo) {
            if (unparsed.Substring(0, 1) == "d") {
                return clsDirDetails.DirectoryDetail.IsSubdirInDir;
            }
            else {
                return clsDirDetails.DirectoryDetail.IsFileInDir;
            }
        }
        
        #region clsDirDetails_StringMethods
        string getPathOrFilename(string unparsedInfo) {
            int j = unparsedInfo.LastIndexOf(' ');
            return unparsedInfo.Substring(j + 1, unparsedInfo.Length - j - 1);
        }
        string getDateTimeString(string unparsedInfo) {
             
            string result = string.Empty;
            int i = getIndexOfDateBeginning(unparsedInfo);
            if (i < 0) {
                clsErrLog errLogger = 
                    new clsErrLog("Error in clsDirDetails: method " +
                    "getDateTimeString()'s sub-method getIndexOfDateBeginning() " + 
                    "returned a value of -1.");
            }
            result = unparsedInfo.Substring(i, unparsedInfo.Length - (i+1));
            int j = result.LastIndexOf(" ");
            result = result.Substring(0, j);
            //if, for whatever reason, we've failed to parse out a 
            //valid DateTime, error-log it
            if (!objectIsDate(result)) {
                clsErrLog errLogger = 
                    new clsErrLog("Error in getDateTimeString() in clsFTPclient.  The " +
                    "parsed result does not appear to be a valid DateTime.");
            }
            return result;
        }
        #endregion
        #region clsDirDetails_BooleanMethods
        bool objectIsDate(Object obj) {
            string strDate = obj.ToString();
            try {
                DateTime dt = DateTime.Parse(strDate);
                if (dt != DateTime.MinValue && dt != DateTime.MaxValue)
                    return true;
                return false;
            }
            catch {
                return false;
            }
        }
        #endregion
        #region clsDirDetails_IntegerMethods
        int getIndexOfFirstAlphabeticCharacter(string source) {
            int i = -1;
            foreach (char c in source) {
                i++;
                if (Char.IsLetter(c)) { return i; }
            }
            return i;
        }
        int getIndexOfDateBeginning(string unparsedInfo) {
            int i = -1;
            
            i = unparsedInfo.IndexOf("Jan");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Feb");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Mar");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Apr");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("May");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Jun");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Jul");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Aug");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Sep");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Oct");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Nov");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Dec");
            if (i > -1) { return i; }            
            return i;
        }
        #endregion
        #endregion
        //next right-brace ends clsDirDetails
    }
    //next right-brace ends namespace Kyrathasoft.NetUtilities.FTPclient
}
                                
                            Revision: 37186
                            
                                                            
                                    
                                        
Updated Code
                                    
                                    
                                                    
                        at January 6, 2011 13:17 by kyrathaba
                            
                            Updated Code
namespace Kyrathasoft.NetUtilities.FTPclient {
    //developed this class on Saturday, 01/01/2011
    //added method DirectoryDetails() on 01/02/2011
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Text;
    using Kyrathasoft.Dialogs.ErrLogging;
    public class clsFTPclient {
        /* 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.         
         * 
         * 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)
         * 
         */
        #region clsFTPclient_PrivateMembers
        // 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;
        #endregion
        #region clsFTPclient_Constructors
        //constructor
        public clsFTPclient(string remoteHost, string remoteUser, 
            string remotePassword) {
            _remoteHost = remoteHost;
            _remoteUser = remoteUser;
            _remotePass = remotePassword;           
        }
        #endregion
        #region clsFTPclient_Methods
        public List<clsDirDetails> DirectoryDetails(string subdirectory) {
            List<clsDirDetails> the_details = new List<clsDirDetails>();
            clsDirDetails details;
            // Get the object used to communicate with the server.
            FtpWebRequest request = 
                (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            request.Credentials = 
                new NetworkCredential(_remoteUser, _remotePass);
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            while (!reader.EndOfStream) {
                details = new clsDirDetails();
                //once .Unparsed is set, clsDirDetails internally calcs 
                //and assigns DirMemberType, LastModified and PathOrFilename
                //These assignments are made just as soon as the .Unparsed
                //property is set, BEFORE details are added to the List
                details.Unparsed = reader.ReadLine();               
                the_details.Add(details);
            }
            return the_details;
        }
        public List<string> DirectoryListing(string subdirectory) {
            /* Examples of how to invoke:
             * 
             * 
             * 
             * 
             * sample button click_event handler follows...
             * =============================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            //gives root directory listing
            List<string> files = client.DirectoryListing(""); 
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + Environment.NewLine;
            }
             * ============================================================
             * 
             * 
             * 
                                        ................
             * 
             * 
             * 
             * another sample button click_event handler follows...
             * ===========================+================================
            string username = "my_username";
            string password = "my_password";
            string host = "ftp://mywebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            //lists the /httpdocs/non_church subdirectory
            List<string> files = client.DirectoryListing("//httpdocs//non_church");
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + Environment.NewLine;
            }
             * ============================================================ */
             
            List<string> result = new List<string>();
            try {
                FtpWebRequest request = 
                    (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
                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);                
                while (!reader.EndOfStream) {
                    result.Add(reader.ReadLine());
                }
                reader.Close();
                response.Close();
                return result;
            }
            catch (Exception ex) {
                clsErrLog errLog = new clsErrLog("Error in clsFTPclient.DirectoryListing():" +                                    Environment.NewLine + ex.Message);                
                return result;
            }
        }
        public void DownloadFile(string file, string destination) {
            /* Examples of how to invoke:
             * 
             *              * sample button click_event handler follows...
             * ======================================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host + "/httpdocs/downloads/", username, password);
            client.DownloadFile("booksOnServer.html", "downloadedToLocalDirectory.html");
            }
             * ===================================================================== */
             
            if (FileExistsAtThisURI(_remoteHost + file, _remoteUser, 
                _remotePass)) {
                try {
                    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();
                }
                catch (Exception ex) {
                    clsErrLog errLogger = 
                        new clsErrLog("Error in clsFTPclient.DownloadFile()" +                                                                      Environment.NewLine + ex.Message);                    
                }
            }
            else {
                clsErrLog errLogger = 
                    new clsErrLog("Error in clsFTPclient.DownloadFile(): " +                                                                Environment.NewLine + "The file you're attempting to download, '" + 
                    (_remoteHost + file) +
                    "', doesn't exist on the server at the URI you specified when " +
                    "you invoked the Download method.");
            }
        }
        public bool FileExistsAtThisURI(string fullFtpFilepath, string userName, 
            string passWord) {
            bool exists = true;
            var request = 
                (FtpWebRequest)WebRequest.Create(fullFtpFilepath);
            request.Credentials = 
                new NetworkCredential(userName, passWord);
            request.Method = 
                WebRequestMethods.Ftp.GetDateTimestamp;
            try {
                FtpWebResponse response = 
                    (FtpWebResponse)request.GetResponse();
            }
            catch (WebException ex) {
                FtpWebResponse response = (FtpWebResponse)ex.Response;
                if (response.StatusCode ==
                    FtpStatusCode.ActionNotTakenFileUnavailable) {
                    exists = false; //Does not exist
                }
            }
            return exists;
        }
        public void UploadFile(string FullPathFilename) {
            /* Be sure to invoke UploadFile on an asynch thread, 
             * like on a backgroundWorker...
             
            private void backgroundWorker1_DoWork(object sender, 
             * System.ComponentModel.DoWorkEventArgs e) {
            
                string username = "my_username";
                string password = "my_password";
                string host = "ftp://mywebsite.com";
                string myLocal = Path.GetDirectoryName(Application.ExecutablePath) + 
                   "\\myTextFile.txt";
                string myRemote = host + "/httpdocs/non_church/";        
                clsFTPclient client = new clsFTPclient(myRemote, username, password);            
                client.UploadFile(myLocal);
            }
             * 
             *                     ... or, rather than use a backgroundWorker...
             *                     
             * set up the same variables as above (username, password, host, myLocal, myRemote)
             * 
             * instantiate client as shown above, and then....
             * 
             * new System.Threading.Thread(() => 
             *      client.UploadFile(Path.GetDirectoryName(Application.ExecutablePath) + 
                    "\\myTextFile.txt")).Start(); */
            string filename = Path.GetFileName(FullPathFilename);
            try {
                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();
            }
            catch (Exception ex) {
                clsErrLog errLogger = 
                    new clsErrLog("Error in clsFTPclient.UploadFile()" + 
                    Environment.NewLine + ex.Message);                
            }            
        }
        #endregion
        //next right-brace ends clsFTPclient
    }    
    public class clsDirDetails {
        //a class to hold, in a convenient way, the details that are returned
        //by WebRequestMethods.Ftp.ListDirectoryDetails
        public enum DirectoryDetail { IsFileInDir, IsSubdirInDir };
        #region clsDirDetails_PrivateMembers
        private DirectoryDetail dirMemberType; //is it a file or subdirectory?
        private string pathOrFilename; //path of subdir or filename if it's a file
        private string lastModified; //last time file got modified (applies to files only)
        private string unparsed; //the unparsed line that contains details
        private string ownerPermissions; //usually this will be rwx (read/write/execute)
        private bool ownerCanRead; //owner CAN or CANNOT read the specified dir/file
        private bool ownerCanWrite; //same as above, except WRITE rather than READ
        private bool ownerCanExecute; //same as above, except EXECUTE rather than WRITE
        #endregion
        #region clsDirDetails_Properties
        //is it a file or a subdirectory?
        public DirectoryDetail DirMemberType {
            get { return dirMemberType; }
            set { dirMemberType = value; }
        }
        //owner permissions
        public string OwnerPermissions {
            get { return ownerPermissions; }
            set { ownerPermissions = value; }
        }
        //owner can read?
        public bool OwnerCanRead {
            get { return ownerCanRead; }
            set { ownerCanRead = value; }
        }
        //owner can write?
        public bool OwnerCanWrite {
            get { return ownerCanWrite; }
            set { ownerCanWrite = value; }
        }
        //owner can execute?
        public bool OwnerCanExecute {
            get { return OwnerCanExecute; }
            set { ownerCanExecute = value; }
        }
        //the full path
        public string PathOrFilename {
            get { return pathOrFilename; }
            set { pathOrFilename = value; }
        }
        //for files only...
        public string LastModified {
            get { return lastModified; }
            set { lastModified = value; }
        }
        //the unparsed line that contains details
        public string Unparsed {
            get { return unparsed; }
            set {
                unparsed = value;
                LastModified = getDateTimeString(unparsed);
                //also parse out the subdir path or filename                
                PathOrFilename = getPathOrFilename(unparsed);
                //assign DirMemberType
                DirMemberType = getDirectoryDetail(unparsed);
                //assign OwnerPermissions
                ownerPermissions = unparsed.Substring(1, 3);
                if (ownerPermissions.Contains("r")) { 
                    ownerCanRead = true; } 
                else { ownerCanRead = false; }
                if (ownerPermissions.Contains("w")) { 
                    ownerCanWrite = true; } 
                else { ownerCanWrite = false; }
                if (ownerPermissions.Contains("x")) { 
                    ownerCanExecute = true; } 
                else { ownerCanExecute = false; }
                //next right-brace ends set accessor of Unparsed property
            }
            //next right-brace ends Property Unparsed
        }
        #endregion
        #region clsDirDetails_Methods
        clsDirDetails.DirectoryDetail getDirectoryDetail(string unparsedInfo) {
            if (unparsed.Substring(0, 1) == "d") {
                return clsDirDetails.DirectoryDetail.IsSubdirInDir;
            }
            else {
                return clsDirDetails.DirectoryDetail.IsFileInDir;
            }
        }
        
        #region clsDirDetails_StringMethods
        string getPathOrFilename(string unparsedInfo) {
            int j = unparsedInfo.LastIndexOf(' ');
            return unparsedInfo.Substring(j + 1, unparsedInfo.Length - j - 1);
        }
        string getDateTimeString(string unparsedInfo) {
             
            string result = string.Empty;
            int i = getIndexOfDateBeginning(unparsedInfo);
            if (i < 0) {
                clsErrLog errLogger = 
                    new clsErrLog("Error in clsDirDetails: method " +
                    "getDateTimeString()'s sub-method getIndexOfDateBeginning() " + 
                    "returned a value of -1.");
            }
            result = unparsedInfo.Substring(i, unparsedInfo.Length - (i+1));
            int j = result.LastIndexOf(" ");
            result = result.Substring(0, j);
            //if, for whatever reason, we've failed to parse out a 
            //valid DateTime, error-log it
            if (!objectIsDate(result)) {
                clsErrLog errLogger = 
                    new clsErrLog("Error in getDateTimeString() in clsFTPclient.  The " +
                    "parsed result does not appear to be a valid DateTime.");
            }
            return result;
        }
        #endregion
        #region clsDirDetails_BooleanMethods
        bool objectIsDate(Object obj) {
            string strDate = obj.ToString();
            try {
                DateTime dt = DateTime.Parse(strDate);
                if (dt != DateTime.MinValue && dt != DateTime.MaxValue)
                    return true;
                return false;
            }
            catch {
                return false;
            }
        }
        #endregion
        #region clsDirDetails_IntegerMethods
        int getIndexOfFirstAlphabeticCharacter(string source) {
            int i = -1;
            foreach (char c in source) {
                i++;
                if (Char.IsLetter(c)) { return i; }
            }
            return i;
        }
        int getIndexOfDateBeginning(string unparsedInfo) {
            int i = -1;
            
            i = unparsedInfo.IndexOf("Jan");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Feb");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Mar");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Apr");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("May");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Jun");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Jul");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Aug");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Sep");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Oct");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Nov");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Dec");
            if (i > -1) { return i; }            
            return i;
        }
        #endregion
        #endregion
        //next right-brace ends clsDirDetails
    }
    //next right-brace ends namespace Kyrathasoft.NetUtilities.FTPclient
}
                                
                            Revision: 37185
                            
                                                            
                                    
                                        
Updated Code
                                    
                                    
                                                    
                        at January 6, 2011 12:24 by kyrathaba
                            
                            Updated Code
namespace Kyrathasoft.NetUtilities.FTPclient {
    //developed this class on Saturday, 01/01/2011
    //added method DirectoryDetails() on 01/02/2011
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Text;
    using Kyrathasoft.Dialogs.ErrLogging;
    public class clsFTPclient {
        /* 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.         
         * 
         * 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)
         * 
         */
        #region clsFTPclientPrivateMembers
        // 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;
        #endregion
        //constructor
        public clsFTPclient(string remoteHost, string remoteUser, string remotePassword) {
            _remoteHost = remoteHost;
            _remoteUser = remoteUser;
            _remotePass = remotePassword;           
        }
        #region clsFTPclientMethods
        public List<clsDirDetails> DirectoryDetails(string subdirectory) {
            List<clsDirDetails> the_details = new List<clsDirDetails>();
            clsDirDetails details;
            // Get the object used to communicate with the server.
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            while (!reader.EndOfStream) {
                details = new clsDirDetails();
                //once .Unparsed is set, clsDirDetails internally calcs and assigns
                //DirMemberType, LastModified and PathOrFilename
                details.Unparsed = reader.ReadLine();               
                the_details.Add(details);
            }
            return the_details;
        }
        public List<string> DirectoryListing(string subdirectory) {
            /*
             * //Examples of how to invoke:
             * 
             * 
             * 
             * 
             * sample button click_event handler follows...
             * ======================================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            List<string> files = client.DirectoryListing(""); //gives root directory listing
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + Environment.NewLine;
            }
             * ======================================================================
             * 
             * 
             * 
                                        ................
             * 
             * 
             * 
             * another sample button click_event handler follows...
             * ======================================================================
            string username = "my_username";
            string password = "my_password";
            string host = "ftp://mywebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            //lists the /httpdocs/non_church subdirectory
            List<string> files = client.DirectoryListing("//httpdocs//non_church");
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + Environment.NewLine;
            }
             * ======================================================================
             * 
             */
            List<string> result = new List<string>();
            try {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
                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);                
                while (!reader.EndOfStream) {
                    result.Add(reader.ReadLine());
                }
                reader.Close();
                response.Close();
                return result;
            }
            catch (Exception ex) {
                clsErrLog errLog = new clsErrLog("Error in clsFTPclient.DirectoryListing():" +                                    Environment.NewLine + ex.Message);
                
                return result;
            }
        }
        public void DownloadFile(string file, string destination) {
            /*
             *      //Examples of how to invoke:
             * 
             * 
             * 
             *              * sample button click_event handler follows...
             * ======================================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host + "/httpdocs/downloads/", username, password);
            client.DownloadFile("booksOnServer.html", "downloadedToLocalDirectory.html");
            }
             * ======================================================================
             * 
             * 
             */
            if (FileExistsAtThisURI(_remoteHost + file, _remoteUser, _remotePass)) {
                try {
                    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();
                }
                catch (Exception ex) {
                    clsErrLog errLogger = new clsErrLog("Error in clsFTPclient.DownloadFile()" +                                      Environment.NewLine + ex.Message);                    
                }
            }
            else {
                clsErrLog errLogger = new clsErrLog("Error in clsFTPclient.DownloadFile(): " +                                    Environment.NewLine + "The file you're attempting to download, '" + (_remoteHost + file) +
          "', doesn't exist on the server at the URI you specified when you invoked the Download method.");
            }
        }
        public bool FileExistsAtThisURI(string fullFtpFilepath, string userName, string passWord) {
            bool exists = true;
            var request = (FtpWebRequest)WebRequest.Create(fullFtpFilepath);
            request.Credentials = new NetworkCredential(userName, passWord);
            request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
            try {
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            }
            catch (WebException ex) {
                FtpWebResponse response = (FtpWebResponse)ex.Response;
                if (response.StatusCode ==
                    FtpStatusCode.ActionNotTakenFileUnavailable) {
                    exists = false; //Does not exist
                }
            }
            return exists;
        }
        public void UploadFile(string FullPathFilename) {
            /* Be sure to invoke UploadFile on an asynch thread, like on a backgroundWorker...
             
            private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {
            
                string username = "my_username";
                string password = "my_password";
                string host = "ftp://mywebsite.com";
                string myLocal = Path.GetDirectoryName(Application.ExecutablePath) + "\\myTextFile.txt";
                string myRemote = host + "/httpdocs/non_church/";        
                clsFTPclient client = new clsFTPclient(myRemote, username, password);            
                client.UploadFile(myLocal);
            }
             * 
             *                     ... or, rather than use a backgroundWorker...
             *                     
             * set up the same variables as above (username, password, host, myLocal, myRemote)
             * 
             * instantiate client as shown above, and then....
             * 
             * new System.Threading.Thread(() => client.UploadFile(Path.GetDirectoryName(Application.ExecutablePath) + 
                "\\myTextFile.txt")).Start();
             *  
             */
            string filename = Path.GetFileName(FullPathFilename);
            try {
                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();
            }
            catch (Exception ex) {
                clsErrLog errLogger = new clsErrLog("Error in clsFTPclient.UploadFile()" + 
                    Environment.NewLine + ex.Message);                
            }            
        }
        #endregion
        //next right-brace ends clsFTPclient
    }
    
    public class clsDirDetails {
        //a class to hold, in a convenient way, the details that are returned
        //by WebRequestMethods.Ftp.ListDirectoryDetails
        public enum DirectoryDetail { IsFileInDir, IsSubdirInDir };
        private DirectoryDetail dirMemberType; //is it a file or subdirectory?
        private string pathOrFilename; //path of subdir or filename if it's a file
        private string lastModified; //last time file got modified (applies to files only)
        private string unparsed; //the unparsed line that contains details
        private string ownerPermissions; //usually this will be rwx (read/write/execute)
        private bool ownerCanRead; //owner CAN or CANNOT read the specified dir/file
        private bool ownerCanWrite; //same as above, except WRITE rather than READ
        private bool ownerCanExecute; //same as above, except EXECUTE rather than WRITE
        //is it a file or a subdirectory?
        public DirectoryDetail DirMemberType {
            get { return dirMemberType; }
            set { dirMemberType = value; }
        }
        //owner permissions
        public string OwnerPermissions {
            get { return ownerPermissions; }
            set { ownerPermissions = value; }
        }
        //owner can read?
        public bool OwnerCanRead {
            get { return ownerCanRead; }
            set { ownerCanRead = value; }
        }
        //owner can write?
        public bool OwnerCanWrite {
            get { return ownerCanWrite; }
            set { ownerCanWrite = value; }
        }
        //owner can execute?
        public bool OwnerCanExecute {
            get { return OwnerCanExecute; }
            set { ownerCanExecute = value; }
        }
        //the full path
        public string PathOrFilename {
            get { return pathOrFilename; }
            set { pathOrFilename = value; }
        }
        //for files only...
        public string LastModified {
            get { return lastModified; }
            set { lastModified = value; }
        }
        //the unparsed line that contains details
        public string Unparsed {
            get { return unparsed; }
            set {  unparsed = value;
                LastModified = getDateTimeString(unparsed);
                //also parse out the subdir path or filename                
                PathOrFilename = getPathOrFilename(unparsed);
                //assign DirMemberType
                DirMemberType = getDirectoryDetail(unparsed);
                //assign OwnerPermissions
                ownerPermissions = unparsed.Substring(1, 3);
                if(ownerPermissions.Contains("r")){ ownerCanRead = true;}else{ownerCanRead = false;}
                if (ownerPermissions.Contains("w")) { ownerCanWrite = true; } else { ownerCanWrite = false; }
                if (ownerPermissions.Contains("x")) { ownerCanExecute = true; } else { ownerCanExecute = false; }
                
                //next right-brace ends set accessor of Unparsed property
            }
            //next right-brace ends Property Unparsed
        }
        clsDirDetails.DirectoryDetail getDirectoryDetail(string unparsedInfo) {
            if (unparsed.Substring(0, 1) == "d") {
                return clsDirDetails.DirectoryDetail.IsSubdirInDir;
            }
            else {
                return clsDirDetails.DirectoryDetail.IsFileInDir;
            }
        }
        string getPathOrFilename(string unparsedInfo) {
            int j = unparsedInfo.LastIndexOf(' ');
            return unparsedInfo.Substring(j + 1, unparsedInfo.Length - j - 1);
        }
        string getDateTimeString(string unparsedInfo) {
             
            string result = string.Empty;
            int i = getIndexOfDateBeginning(unparsedInfo);
            if (i < 0) {
                clsErrLog errLogger = new clsErrLog("Error in clsDirDetails: method " +
                    "getDateTimeString()'s sub-method getIndexOfDateBeginning() returned a value of -1.");
            }
            result = unparsedInfo.Substring(i, unparsedInfo.Length - (i+1));
            int j = result.LastIndexOf(" ");
            result = result.Substring(0, j);
            return result;
        }
        int getIndexOfFirstAlphabeticCharacter(string source) {
            int i = -1;
            foreach (char c in source) {
                i++;
                if (Char.IsLetter(c)) { return i; }
            }
            return i;
        }
        int getIndexOfDateBeginning(string unparsedInfo) {
            int i = -1;
            
            i = unparsedInfo.IndexOf("Jan");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Feb");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Mar");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Apr");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("May");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Jun");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Jul");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Aug");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Sep");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Oct");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Nov");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Dec");
            if (i > -1) { return i; }            
            return i;
        }
        //next right-brace ends clsDirDetails
    }
    //next right-brace ends namespace Kyrathasoft.NetUtilities.FTPclient
}
                                
                            Revision: 37184
                            
                                                            
                                    
                                        
Updated Code
                                    
                                    
                                                    
                        at January 6, 2011 11:28 by kyrathaba
                            
                            Updated Code
namespace Kyrathasoft.NetUtilities.FTPclient {
    //developed this class on Saturday, 01/01/2011
    //added method DirectoryDetails() on 01/02/2011
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Text;
    using Kyrathasoft.Dialogs;
    public class clsFTPclient {
        /* 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.         
         * 
         * 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)
         * 
         */
        #region clsFTPclientPrivateMembers
        // 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;
        #endregion
        //constructor
        public clsFTPclient(string remoteHost, string remoteUser, string remotePassword) {
            _remoteHost = remoteHost;
            _remoteUser = remoteUser;
            _remotePass = remotePassword;           
        }
        #region clsFTPclientMethods
        public List<clsDirDetails> DirectoryDetails(string subdirectory) {
            List<clsDirDetails> the_details = new List<clsDirDetails>();
            clsDirDetails details;
            // Get the object used to communicate with the server.
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            while (!reader.EndOfStream) {
                details = new clsDirDetails();
                //once .Unparsed is set, clsDirDetails internally calcs and assigns
                //DirMemberType, LastModified and PathOrFilename
                details.Unparsed = reader.ReadLine();               
                the_details.Add(details);
            }
            return the_details;
        }
        public List<string> DirectoryListing(string subdirectory) {
            /*
             * //Examples of how to invoke:
             * 
             * 
             * 
             * 
             * sample button click_event handler follows...
             * ======================================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            List<string> files = client.DirectoryListing(""); //gives root directory listing
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + Environment.NewLine;
            }
             * ======================================================================
             * 
             * 
             * 
                                        ................
             * 
             * 
             * 
             * another sample button click_event handler follows...
             * ======================================================================
            string username = "my_username";
            string password = "my_password";
            string host = "ftp://mywebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            //lists the /httpdocs/non_church subdirectory
            List<string> files = client.DirectoryListing("//httpdocs//non_church");
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + Environment.NewLine;
            }
             * ======================================================================
             * 
             */
            List<string> result = new List<string>();
            try {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
                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);                
                while (!reader.EndOfStream) {
                    result.Add(reader.ReadLine());
                }
                reader.Close();
                response.Close();
                return result;
            }
            catch (Exception ex) {
                clsErrLog errLog = new clsErrLog("Error in clsFTPclient.DirectoryListing():" +                                    Environment.NewLine + ex.Message);
                
                return result;
            }
        }
        public void DownloadFile(string file, string destination) {
            /*
             *      //Examples of how to invoke:
             * 
             * 
             * 
             *              * sample button click_event handler follows...
             * ======================================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host + "/httpdocs/downloads/", username, password);
            client.DownloadFile("booksOnServer.html", "downloadedToLocalDirectory.html");
            }
             * ======================================================================
             * 
             * 
             */
            if (FileExistsAtThisURI(_remoteHost + file, _remoteUser, _remotePass)) {
                try {
                    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();
                }
                catch (Exception ex) {
                    clsErrLog errLogger = new clsErrLog("Error in clsFTPclient.DownloadFile()" +                                      Environment.NewLine + ex.Message);                    
                }
            }
            else {
                clsErrLog errLogger = new clsErrLog("Error in clsFTPclient.DownloadFile(): " +                                    Environment.NewLine + "The file you're attempting to download, '" + (_remoteHost + file) +
                    "', doesn't exist on the server at the URI you specified when you invoked the Download method.");
            }
        }
        public bool FileExistsAtThisURI(string fullFtpFilepath, string userName, string passWord) {
            bool exists = true;
            var request = (FtpWebRequest)WebRequest.Create(fullFtpFilepath);
            request.Credentials = new NetworkCredential(userName, passWord);
            request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
            try {
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            }
            catch (WebException ex) {
                FtpWebResponse response = (FtpWebResponse)ex.Response;
                if (response.StatusCode ==
                    FtpStatusCode.ActionNotTakenFileUnavailable) {
                    exists = false; //Does not exist
                }
            }
            return exists;
        }
        public void UploadFile(string FullPathFilename) {
            /* Be sure to invoke UploadFile on an asynch thread, like on a backgroundWorker...
             
            private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {
            
                string username = "my_username";
                string password = "my_password";
                string host = "ftp://mywebsite.com";
                string myLocal = Path.GetDirectoryName(Application.ExecutablePath) + "\\myTextFile.txt";
                string myRemote = host + "/httpdocs/non_church/";        
                clsFTPclient client = new clsFTPclient(myRemote, username, password);            
                client.UploadFile(myLocal);
            }
             * 
             *                     ... or, rather than use a backgroundWorker...
             *                     
             * set up the same variables as above (username, password, host, myLocal, myRemote)
             * 
             * instantiate client as shown above, and then....
             * 
             * new System.Threading.Thread(() => client.UploadFile(Path.GetDirectoryName(Application.ExecutablePath) + 
                "\\myTextFile.txt")).Start();
             *  
             */
            string filename = Path.GetFileName(FullPathFilename);
            try {
                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();
            }
            catch (Exception ex) {
                clsErrLog errLogger = new clsErrLog("Error in clsFTPclient.UploadFile()" + 
                    Environment.NewLine + ex.Message);                
            }            
        }
        #endregion
        //next right-brace ends clsFTPclient
    }
    
    public class clsDirDetails {
        //a class to hold, in a convenient way, the details that are returned
        //by WebRequestMethods.Ftp.ListDirectoryDetails
        public enum DirectoryDetail { IsFileInDir, IsSubdirInDir };
        private DirectoryDetail dirMemberType; //is it a file or subdirectory?
        private string pathOrFilename; //path of subdir or filename if it's a file
        private string lastModified; //last time file got modified (applies to files only)
        private string unparsed; //the unparsed line that contains details
        private string ownerPermissions; //usually this will be rwx (read/write/execute)
        private bool ownerCanRead; //owner CAN or CANNOT read the specified dir/file
        private bool ownerCanWrite; //same as above, except WRITE rather than READ
        private bool ownerCanExecute; //same as above, except EXECUTE rather than WRITE
        //is it a file or a subdirectory?
        public DirectoryDetail DirMemberType {
            get { return dirMemberType; }
            set { dirMemberType = value; }
        }
        //owner permissions
        public string OwnerPermissions {
            get { return ownerPermissions; }
            set { ownerPermissions = value; }
        }
        //owner can read?
        public bool OwnerCanRead {
            get { return ownerCanRead; }
            set { ownerCanRead = value; }
        }
        //owner can write?
        public bool OwnerCanWrite {
            get { return ownerCanWrite; }
            set { ownerCanWrite = value; }
        }
        //owner can execute?
        public bool OwnerCanExecute {
            get { return OwnerCanExecute; }
            set { ownerCanExecute = value; }
        }
        //the full path
        public string PathOrFilename {
            get { return pathOrFilename; }
            set { pathOrFilename = value; }
        }
        //for files only...
        public string LastModified {
            get { return lastModified; }
            set { lastModified = value; }
        }
        //the unparsed line that contains details
        public string Unparsed {
            get { return unparsed; }
            set {  unparsed = value;
                LastModified = getDateTimeString(unparsed);
                //also parse out the subdir path or filename                
                PathOrFilename = getPathOrFilename(unparsed);
                //assign DirMemberType
                DirMemberType = getDirectoryDetail(unparsed);
                //assign OwnerPermissions
                ownerPermissions = unparsed.Substring(1, 3);
                if(ownerPermissions.Contains("r")){ ownerCanRead = true;}else{ownerCanRead = false;}
                if (ownerPermissions.Contains("w")) { ownerCanWrite = true; } else { ownerCanWrite = false; }
                if (ownerPermissions.Contains("x")) { ownerCanExecute = true; } else { ownerCanExecute = false; }
                
                //next right-brace ends set accessor of Unparsed property
            }
            //next right-brace ends Property Unparsed
        }
        clsDirDetails.DirectoryDetail getDirectoryDetail(string unparsedInfo) {
            if (unparsed.Substring(0, 1) == "d") {
                return clsDirDetails.DirectoryDetail.IsSubdirInDir;
            }
            else {
                return clsDirDetails.DirectoryDetail.IsFileInDir;
            }
        }
        string getPathOrFilename(string unparsedInfo) {
            int j = unparsedInfo.LastIndexOf(' ');
            return unparsedInfo.Substring(j + 1, unparsedInfo.Length - j - 1);
        }
        string getDateTimeString(string unparsedInfo) {
             
            string result = string.Empty;
            int i = getIndexOfDateBeginning(unparsedInfo);
            if (i < 0) {
                clsErrLog errLogger = new clsErrLog("Error in clsDirDetails: method " +
                    "getDateTimeString()'s sub-method getIndexOfDateBeginning() returned a value of -1.");
            }
            result = unparsedInfo.Substring(i, unparsedInfo.Length - (i+1));
            int j = result.LastIndexOf(" ");
            result = result.Substring(0, j);
            return result;
        }
        int getIndexOfFirstAlphabeticCharacter(string source) {
            int i = -1;
            foreach (char c in source) {
                i++;
                if (Char.IsLetter(c)) { return i; }
            }
            return i;
        }
        int getIndexOfDateBeginning(string unparsedInfo) {
            int i = -1;
            
            i = unparsedInfo.IndexOf("Jan");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Feb");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Mar");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Apr");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("May");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Jun");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Jul");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Aug");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Sep");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Oct");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Nov");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Dec");
            if (i > -1) { return i; }            
            return i;
        }
        //next right-brace ends clsDirDetails
    }
    //next right-brace ends namespace Kyrathasoft.NetUtilities.FTPclient
}
/*
 * The clsFTPclient.cs class shown above makes use of clsErrLog.cs shown below
 *
 */
namespace Kyrathasoft.Dialogs {
    using System;
    using System.IO;
    using System.Windows.Forms;
    class clsErrLog {
        public clsErrLog() {
            //set default path for error log text file
            errLogPath = Path.GetDirectoryName(Application.ExecutablePath) + "\\errorLog.txt"; 
        }
        public clsErrLog(string errTxt) {
            //set default path for error log text file
            errLogPath = Path.GetDirectoryName(Application.ExecutablePath) + "\\errorLog.txt";
            updateErrorLog(errTxt);
        }
        public clsErrLog(string errTxt, string full_path) {
            errLogPath = full_path;
            updateErrorLog(errTxt);
        }
        private string errLogPath;
        public string ErrLogPath {
            get { return errLogPath; }
            set { errLogPath = value; }
        }
        private void updateErrorLog(string errorText) {
            string msg = Environment.NewLine + Environment.NewLine;
            msg += DateTime.Now.ToString() + Environment.NewLine + errorText;
            File.AppendAllText(errLogPath, msg);
        }
    }
}
                                
                            Revision: 37183
                            
                                                            
                                    
                                        
Updated Code
                                    
                                    
                                                    
                        at January 6, 2011 11:27 by kyrathaba
                            
                            Updated Code
namespace Kyrathasoft.NetUtilities.FTPclient {
    //developed this class on Saturday, 01/01/2011
    //added method DirectoryDetails() on 01/02/2011
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Windows.Forms;
    public class clsFTPclient {
        /* 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.         
         * 
         * 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)
         * 
         */
        #region clsFTPclientPrivateMembers
        // 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;
        #endregion
        //constructor
        public clsFTPclient(string remoteHost, string remoteUser, string remotePassword) {
            _remoteHost = remoteHost;
            _remoteUser = remoteUser;
            _remotePass = remotePassword;           
        }
        #region clsFTPclientMethods
        public List<clsDirDetails> DirectoryDetails(string subdirectory) {
            List<clsDirDetails> the_details = new List<clsDirDetails>();
            clsDirDetails details;
            // Get the object used to communicate with the server.
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            while (!reader.EndOfStream) {
                details = new clsDirDetails();
                //once .Unparsed is set, clsDirDetails internally calcs and assigns
                //DirMemberType, LastModified and PathOrFilename
                details.Unparsed = reader.ReadLine();               
                the_details.Add(details);
            }
            return the_details;
        }
        public List<string> DirectoryListing(string subdirectory) {
            /*
             * //Examples of how to invoke:
             * 
             * 
             * 
             * 
             * sample button click_event handler follows...
             * ======================================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            List<string> files = client.DirectoryListing(""); //gives root directory listing
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + Environment.NewLine;
            }
             * ======================================================================
             * 
             * 
             * 
                                        ................
             * 
             * 
             * 
             * another sample button click_event handler follows...
             * ======================================================================
            string username = "my_username";
            string password = "my_password";
            string host = "ftp://mywebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            //lists the /httpdocs/non_church subdirectory
            List<string> files = client.DirectoryListing("//httpdocs//non_church");
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + Environment.NewLine;
            }
             * ======================================================================
             * 
             */
            List<string> result = new List<string>();
            try {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
                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);                
                while (!reader.EndOfStream) {
                    result.Add(reader.ReadLine());
                }
                reader.Close();
                response.Close();
                return result;
            }
            catch (Exception ex) {
                updateErrorLog("Error in clsFTPclient.DirectoryListing():" + Environment.NewLine +
                    ex.Message);
                
                return result;
            }
        }
        public void DownloadFile(string file, string destination) {
            /*
             *      //Examples of how to invoke:
             * 
             * 
             * 
             *              * sample button click_event handler follows...
             * ======================================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host + "/httpdocs/downloads/", username, password);
            client.DownloadFile("booksOnServer.html", "downloadedToLocalDirectory.html");
            }
             * ======================================================================
             * 
             * 
             */
            if (FileExistsAtThisURI(_remoteHost + file, _remoteUser, _remotePass)) {
                try {
                    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();
                }
                catch (Exception ex) {
                    updateErrorLog("Error in clsFTPclient.DownloadFile()" + Environment.NewLine + ex.Message);
                }
            }
            else {
                updateErrorLog("Error in clsFTPclient.DownloadFile(): " + Environment.NewLine +
                    "The file you're attempting to download, '" + (_remoteHost + file) + 
                    "', doesn't exist on the server at the URI you specified when you invoked the Download method.");
            }
        }
        public bool FileExistsAtThisURI(string fullFtpFilepath, string userName, string passWord) {
            bool exists = true;
            var request = (FtpWebRequest)WebRequest.Create(fullFtpFilepath);
            request.Credentials = new NetworkCredential(userName, passWord);
            request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
            try {
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            }
            catch (WebException ex) {
                FtpWebResponse response = (FtpWebResponse)ex.Response;
                if (response.StatusCode ==
                    FtpStatusCode.ActionNotTakenFileUnavailable) {
                    exists = false; //Does not exist
                }
            }
            return exists;
        }
        public void UploadFile(string FullPathFilename) {
            /* Be sure to invoke UploadFile on an asynch thread, like on a backgroundWorker...
             
            private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {
            
                string username = "my_username";
                string password = "my_password";
                string host = "ftp://mywebsite.com";
                string myLocal = Path.GetDirectoryName(Application.ExecutablePath) + "\\myTextFile.txt";
                string myRemote = host + "/httpdocs/non_church/";        
                clsFTPclient client = new clsFTPclient(myRemote, username, password);            
                client.UploadFile(myLocal);
            }
             * 
             *                     ... or, rather than use a backgroundWorker...
             *                     
             * set up the same variables as above (username, password, host, myLocal, myRemote)
             * 
             * instantiate client as shown above, and then....
             * 
             * new System.Threading.Thread(() => client.UploadFile(Path.GetDirectoryName(Application.ExecutablePath) + 
                "\\myTextFile.txt")).Start();
             *  
             */
            string filename = Path.GetFileName(FullPathFilename);
            try {
                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();
            }
            catch (Exception ex) {
                updateErrorLog("Error in clsFTPclient.UploadFile()" + Environment.NewLine + ex.Message);
            }
            finally {
            }
        }
        private void updateErrorLog(string errorText) {
            string path = Path.GetDirectoryName(Application.ExecutablePath) + "\\clsFTPclientErrorLog.txt";           
            string msg = Environment.NewLine + Environment.NewLine;
            msg += DateTime.Now.ToString() + Environment.NewLine + errorText;
            File.AppendAllText(path, msg);
        }
        #endregion
        //next right-brace ends clsFTPclient
    }
    public class clsDirDetails {
        //a class to hold, in a convenient way, the details that are returned
        //by WebRequestMethods.Ftp.ListDirectoryDetails
        public enum DirectoryDetail { IsFileInDir, IsSubdirInDir };
        private DirectoryDetail dirMemberType; //is it a file or subdirectory?
        private string pathOrFilename; //path of subdir or filename if it's a file
        private string lastModified; //last time file got modified (applies to files only)
        private string unparsed; //the unparsed line that contains details
        private string ownerPermissions; //usually this will be rwx (read/write/execute)
        private bool ownerCanRead; //owner CAN or CANNOT read the specified dir/file
        private bool ownerCanWrite; //same as above, except WRITE rather than READ
        private bool ownerCanExecute; //same as above, except EXECUTE rather than WRITE
        //is it a file or a subdirectory?
        public DirectoryDetail DirMemberType {
            get { return dirMemberType; }
            set { dirMemberType = value; }
        }
        //owner permissions
        public string OwnerPermissions {
            get { return ownerPermissions; }
            set { ownerPermissions = value; }
        }
        //owner can read?
        public bool OwnerCanRead {
            get { return ownerCanRead; }
            set { ownerCanRead = value; }
        }
        //owner can write?
        public bool OwnerCanWrite {
            get { return ownerCanWrite; }
            set { ownerCanWrite = value; }
        }
        //owner can execute?
        public bool OwnerCanExecute {
            get { return OwnerCanExecute; }
            set { ownerCanExecute = value; }
        }
        //the full path
        public string PathOrFilename {
            get { return pathOrFilename; }
            set { pathOrFilename = value; }
        }
        //for files only...
        public string LastModified {
            get { return lastModified; }
            set { lastModified = value; }
        }
        //the unparsed line that contains details
        public string Unparsed {
            get { return unparsed; }
            set {  unparsed = value;
                LastModified = getDateTimeString(unparsed);
                //also parse out the subdir path or filename                
                PathOrFilename = getPathOrFilename(unparsed);
                //assign DirMemberType
                DirMemberType = getDirectoryDetail(unparsed);
                //assign OwnerPermissions
                ownerPermissions = unparsed.Substring(1, 3);
                if(ownerPermissions.Contains("r")){ ownerCanRead = true;}else{ownerCanRead = false;}
                if (ownerPermissions.Contains("w")) { ownerCanWrite = true; } else { ownerCanWrite = false; }
                if (ownerPermissions.Contains("x")) { ownerCanExecute = true; } else { ownerCanExecute = false; }
                
                //next right-brace ends set accessor of Unparsed property
            }
            //next right-brace ends Property Unparsed
        }
        clsDirDetails.DirectoryDetail getDirectoryDetail(string unparsedInfo) {
            if (unparsed.Substring(0, 1) == "d") {
                return clsDirDetails.DirectoryDetail.IsSubdirInDir;
            }
            else {
                return clsDirDetails.DirectoryDetail.IsFileInDir;
            }
        }
        string getPathOrFilename(string unparsedInfo) {
            int j = unparsedInfo.LastIndexOf(' ');
            return unparsedInfo.Substring(j + 1, unparsedInfo.Length - j - 1);
        }
        string getDateTimeString(string unparsedInfo) {
             
            string result = string.Empty;
            int i = getIndexOfDateBeginning(unparsedInfo);
            result = unparsedInfo.Substring(i, unparsedInfo.Length - (i+1));
            int j = result.LastIndexOf(" ");
            result = result.Substring(0, j);
            return result;
        }
        int getIndexOfFirstAlphabeticCharacter(string source) {
            int i = -1;
            foreach (char c in source) {
                i++;
                if (Char.IsLetter(c)) { return i; }
            }
            return i;
        }
        int getIndexOfDateBeginning(string unparsedInfo) {
            int i = -1;
            
            i = unparsedInfo.IndexOf("Jan");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Feb");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Mar");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Apr");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("May");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Jun");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Jul");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Aug");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Sep");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Oct");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Nov");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Dec");
            if (i > -1) { return i; }
            return i;
        }
        //next right-brace ends clsDirDetails
    }
    //next right-brace ends namespace Kyrathasoft.NetUtilities.FTPclient
}
/*
 * The clsFTPclient.cs class shown above makes use of clsErrLog.cs shown below
 *
 */
namespace Kyrathasoft.Dialogs {
    using System;
    using System.IO;
    using System.Windows.Forms;
    class clsErrLog {
        public clsErrLog() {
            //set default path for error log text file
            errLogPath = Path.GetDirectoryName(Application.ExecutablePath) + "\\errorLog.txt"; 
        }
        public clsErrLog(string errTxt) {
            //set default path for error log text file
            errLogPath = Path.GetDirectoryName(Application.ExecutablePath) + "\\errorLog.txt";
            updateErrorLog(errTxt);
        }
        public clsErrLog(string errTxt, string full_path) {
            errLogPath = full_path;
            updateErrorLog(errTxt);
        }
        private string errLogPath;
        public string ErrLogPath {
            get { return errLogPath; }
            set { errLogPath = value; }
        }
        private void updateErrorLog(string errorText) {
            string msg = Environment.NewLine + Environment.NewLine;
            msg += DateTime.Now.ToString() + Environment.NewLine + errorText;
            File.AppendAllText(errLogPath, msg);
        }
    }
}
                                
                            Revision: 37182
                            
                                                            
                                    
                                        
Updated Code
                                    
                                    
                                                    
                        at January 5, 2011 13:55 by kyrathaba
                            
                            Updated Code
namespace Kyrathasoft.NetUtilities.FTPclient {
    //developed this class on Saturday, 01/01/2011
    //added method DirectoryDetails() on 01/02/2011
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Windows.Forms;
    public class clsFTPclient {
        /* 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.         
         * 
         * 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)
         * 
         */
        #region clsFTPclientPrivateMembers
        // 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;
        #endregion
        //constructor
        public clsFTPclient(string remoteHost, string remoteUser, string remotePassword) {
            _remoteHost = remoteHost;
            _remoteUser = remoteUser;
            _remotePass = remotePassword;           
        }
        #region clsFTPclientMethods
        public List<clsDirDetails> DirectoryDetails(string subdirectory) {
            List<clsDirDetails> the_details = new List<clsDirDetails>();
            clsDirDetails details;
            // Get the object used to communicate with the server.
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            while (!reader.EndOfStream) {
                details = new clsDirDetails();
                //once .Unparsed is set, clsDirDetails internally calcs and assigns
                //DirMemberType, LastModified and PathOrFilename
                details.Unparsed = reader.ReadLine();               
                the_details.Add(details);
            }
            return the_details;
        }
        public List<string> DirectoryListing(string subdirectory) {
            /*
             * //Examples of how to invoke:
             * 
             * 
             * 
             * 
             * sample button click_event handler follows...
             * ======================================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            List<string> files = client.DirectoryListing(""); //gives root directory listing
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + Environment.NewLine;
            }
             * ======================================================================
             * 
             * 
             * 
                                        ................
             * 
             * 
             * 
             * another sample button click_event handler follows...
             * ======================================================================
            string username = "my_username";
            string password = "my_password";
            string host = "ftp://mywebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            //lists the /httpdocs/non_church subdirectory
            List<string> files = client.DirectoryListing("//httpdocs//non_church");
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + Environment.NewLine;
            }
             * ======================================================================
             * 
             */
            List<string> result = new List<string>();
            try {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
                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);                
                while (!reader.EndOfStream) {
                    result.Add(reader.ReadLine());
                }
                reader.Close();
                response.Close();
                return result;
            }
            catch (Exception ex) {
                updateErrorLog("Error in clsFTPclient.DirectoryListing():" + Environment.NewLine +
                    ex.Message);
                
                return result;
            }
        }
        public void DownloadFile(string file, string destination) {
            /*
             *      //Examples of how to invoke:
             * 
             * 
             * 
             *              * sample button click_event handler follows...
             * ======================================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host + "/httpdocs/downloads/", username, password);
            client.DownloadFile("booksOnServer.html", "downloadedToLocalDirectory.html");
            }
             * ======================================================================
             * 
             * 
             */
            if (FileExistsAtThisURI(_remoteHost + file, _remoteUser, _remotePass)) {
                try {
                    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();
                }
                catch (Exception ex) {
                    updateErrorLog("Error in clsFTPclient.DownloadFile()" + Environment.NewLine + ex.Message);
                }
            }
            else {
                updateErrorLog("Error in clsFTPclient.DownloadFile(): " + Environment.NewLine +
                    "The file you're attempting to download, '" + (_remoteHost + file) + 
                    "', doesn't exist on the server at the URI you specified when you invoked the Download method.");
            }
        }
        public bool FileExistsAtThisURI(string fullFtpFilepath, string userName, string passWord) {
            bool exists = true;
            var request = (FtpWebRequest)WebRequest.Create(fullFtpFilepath);
            request.Credentials = new NetworkCredential(userName, passWord);
            request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
            try {
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            }
            catch (WebException ex) {
                FtpWebResponse response = (FtpWebResponse)ex.Response;
                if (response.StatusCode ==
                    FtpStatusCode.ActionNotTakenFileUnavailable) {
                    exists = false; //Does not exist
                }
            }
            return exists;
        }
        public void UploadFile(string FullPathFilename) {
            /* Be sure to invoke UploadFile on an asynch thread, like on a backgroundWorker...
             
            private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {
            
                string username = "my_username";
                string password = "my_password";
                string host = "ftp://mywebsite.com";
                string myLocal = Path.GetDirectoryName(Application.ExecutablePath) + "\\myTextFile.txt";
                string myRemote = host + "/httpdocs/non_church/";        
                clsFTPclient client = new clsFTPclient(myRemote, username, password);            
                client.UploadFile(myLocal);
            }
             * 
             *                     ... or, rather than use a backgroundWorker...
             *                     
             * set up the same variables as above (username, password, host, myLocal, myRemote)
             * 
             * instantiate client as shown above, and then....
             * 
             * new System.Threading.Thread(() => client.UploadFile(Path.GetDirectoryName(Application.ExecutablePath) + 
                "\\myTextFile.txt")).Start();
             *  
             */
            string filename = Path.GetFileName(FullPathFilename);
            try {
                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();
            }
            catch (Exception ex) {
                updateErrorLog("Error in clsFTPclient.UploadFile()" + Environment.NewLine + ex.Message);
            }
            finally {
            }
        }
        private void updateErrorLog(string errorText) {
            string path = Path.GetDirectoryName(Application.ExecutablePath) + "\\clsFTPclientErrorLog.txt";           
            string msg = Environment.NewLine + Environment.NewLine;
            msg += DateTime.Now.ToString() + Environment.NewLine + errorText;
            File.AppendAllText(path, msg);
        }
        #endregion
        //next right-brace ends clsFTPclient
    }
    public class clsDirDetails {
        //a class to hold, in a convenient way, the details that are returned
        //by WebRequestMethods.Ftp.ListDirectoryDetails
        public enum DirectoryDetail { IsFileInDir, IsSubdirInDir };
        private DirectoryDetail dirMemberType; //is it a file or subdirectory?
        private string pathOrFilename; //path of subdir or filename if it's a file
        private string lastModified; //last time file got modified (applies to files only)
        private string unparsed; //the unparsed line that contains details
        private string ownerPermissions; //usually this will be rwx (read/write/execute)
        private bool ownerCanRead; //owner CAN or CANNOT read the specified dir/file
        private bool ownerCanWrite; //same as above, except WRITE rather than READ
        private bool ownerCanExecute; //same as above, except EXECUTE rather than WRITE
        //is it a file or a subdirectory?
        public DirectoryDetail DirMemberType {
            get { return dirMemberType; }
            set { dirMemberType = value; }
        }
        //owner permissions
        public string OwnerPermissions {
            get { return ownerPermissions; }
            set { ownerPermissions = value; }
        }
        //owner can read?
        public bool OwnerCanRead {
            get { return ownerCanRead; }
            set { ownerCanRead = value; }
        }
        //owner can write?
        public bool OwnerCanWrite {
            get { return ownerCanWrite; }
            set { ownerCanWrite = value; }
        }
        //owner can execute?
        public bool OwnerCanExecute {
            get { return OwnerCanExecute; }
            set { ownerCanExecute = value; }
        }
        //the full path
        public string PathOrFilename {
            get { return pathOrFilename; }
            set { pathOrFilename = value; }
        }
        //for files only...
        public string LastModified {
            get { return lastModified; }
            set { lastModified = value; }
        }
        //the unparsed line that contains details
        public string Unparsed {
            get { return unparsed; }
            set {  unparsed = value;
                LastModified = getDateTimeString(unparsed);
                //also parse out the subdir path or filename                
                PathOrFilename = getPathOrFilename(unparsed);
                //assign DirMemberType
                DirMemberType = getDirectoryDetail(unparsed);
                //assign OwnerPermissions
                ownerPermissions = unparsed.Substring(1, 3);
                if(ownerPermissions.Contains("r")){ ownerCanRead = true;}else{ownerCanRead = false;}
                if (ownerPermissions.Contains("w")) { ownerCanWrite = true; } else { ownerCanWrite = false; }
                if (ownerPermissions.Contains("x")) { ownerCanExecute = true; } else { ownerCanExecute = false; }
                
                //next right-brace ends set accessor of Unparsed property
            }
            //next right-brace ends Property Unparsed
        }
        clsDirDetails.DirectoryDetail getDirectoryDetail(string unparsedInfo) {
            if (unparsed.Substring(0, 1) == "d") {
                return clsDirDetails.DirectoryDetail.IsSubdirInDir;
            }
            else {
                return clsDirDetails.DirectoryDetail.IsFileInDir;
            }
        }
        string getPathOrFilename(string unparsedInfo) {
            int j = unparsedInfo.LastIndexOf(' ');
            return unparsedInfo.Substring(j + 1, unparsedInfo.Length - j - 1);
        }
        string getDateTimeString(string unparsedInfo) {
             
            string result = string.Empty;
            int i = getIndexOfDateBeginning(unparsedInfo);
            result = unparsedInfo.Substring(i, unparsedInfo.Length - (i+1));
            int j = result.LastIndexOf(" ");
            result = result.Substring(0, j);
            return result;
        }
        int getIndexOfFirstAlphabeticCharacter(string source) {
            int i = -1;
            foreach (char c in source) {
                i++;
                if (Char.IsLetter(c)) { return i; }
            }
            return i;
        }
        int getIndexOfDateBeginning(string unparsedInfo) {
            int i = -1;
            
            i = unparsedInfo.IndexOf("Jan");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Feb");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Mar");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Apr");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("May");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Jun");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Jul");
            if (i > -1) { return i; }
            
            i = unparsedInfo.IndexOf("Aug");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Sep");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Oct");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Nov");
            if (i > -1) { return i; }
            i = unparsedInfo.IndexOf("Dec");
            if (i > -1) { return i; }
            return i;
        }
        //next right-brace ends clsDirDetails
    }
    //next right-brace ends namespace Kyrathasoft.NetUtilities.FTPclient
}
                                
                            Revision: 37181
                            
                                                            
                                    
                                        
Updated Code
                                    
                                    
                                                    
                        at January 4, 2011 08:21 by kyrathaba
                            
                            Updated Code
namespace Kyrathasoft.NetUtilities.FTPclient {
    //developed this class on Saturday, 01/01/2011
    //added method DirectoryDetails() on 01/02/2011
    using System;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Collections.Generic;
    using System.Windows.Forms;
    public class clsFTPclient {
        /* 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.         
         * 
         * 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)
         * 
         */
        // 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 clsFTPclient(string remoteHost, string remoteUser, string remotePassword) {
            _remoteHost = remoteHost;
            _remoteUser = remoteUser;
            _remotePass = remotePassword;           
        }
        public List<clsDirDetails> DirectoryDetails(string subdirectory) {
            List<clsDirDetails> the_details = new List<clsDirDetails>();
            clsDirDetails details;
            // Get the object used to communicate with the server.
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            while (!reader.EndOfStream) {
                details = new clsDirDetails();
                //once .Unparsed is set, clsDirDetails internally calcs and assigns
                //DirMemberType, LastModified and PathOrFilename
                details.Unparsed = reader.ReadLine();               
                the_details.Add(details);
            }
            return the_details;
        }
        public List<string> DirectoryListing(string subdirectory) {
            /*
             * //Examples of how to invoke:
             * 
             * 
             * 
             * 
             * sample button click_event handler follows...
             * ======================================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            List<string> files = client.DirectoryListing(""); //gives root directory listing
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + Environment.NewLine;
            }
             * ======================================================================
             * 
             * 
             * 
                                        ................
             * 
             * 
             * 
             * another sample button click_event handler follows...
             * ======================================================================
            string username = "my_username";
            string password = "my_password";
            string host = "ftp://mywebsite.com";
            clsFTPclient client = new clsFTPclient(host, username, password);
            //lists the /httpdocs/non_church subdirectory
            List<string> files = client.DirectoryListing("//httpdocs//non_church");
            label1.Text = files.Count.ToString();
            textBox1.Text = string.Empty;
            foreach (string s in files) {
                textBox1.Text += s + Environment.NewLine;
            }
             * ======================================================================
             * 
             */
            List<string> result = new List<string>();
            try {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
                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);                
                while (!reader.EndOfStream) {
                    result.Add(reader.ReadLine());
                }
                reader.Close();
                response.Close();
                return result;
            }
            catch (Exception ex) {
                updateErrorLog("Error in clsFTPclient.DirectoryListing():" + Environment.NewLine +
                    ex.Message);
                
                return result;
            }
        }
        public void DownloadFile(string file, string destination) {
            /*
             *      //Examples of how to invoke:
             * 
             * 
             * 
             *              * sample button click_event handler follows...
             * ======================================================================
            string username = "myUsername";
            string password = "myPassword";
            string host = "ftp://myWebsite.com";
            clsFTPclient client = new clsFTPclient(host + "/httpdocs/downloads/", username, password);
            client.DownloadFile("booksOnServer.html", "downloadedToLocalDirectory.html");
            }
             * ======================================================================
             * 
             * 
             */
            if (FileExistsAtThisURI(_remoteHost + file, _remoteUser, _remotePass)) {
                try {
                    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();
                }
                catch (Exception ex) {
                    updateErrorLog("Error in clsFTPclient.DownloadFile()" + Environment.NewLine + ex.Message);
                }
            }
            else {
                updateErrorLog("Error in clsFTPclient.DownloadFile(): " + Environment.NewLine +
                    "The file you're attempting to download, '" + (_remoteHost + file) + 
                    "', doesn't exist on the server at the URI you specified when you invoked the Download method.");
            }
        }
        public bool FileExistsAtThisURI(string fullFtpFilepath, string userName, string passWord) {
            bool exists = true;
            var request = (FtpWebRequest)WebRequest.Create(fullFtpFilepath);
            request.Credentials = new NetworkCredential(userName, passWord);
            request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
            try {
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            }
            catch (WebException ex) {
                FtpWebResponse response = (FtpWebResponse)ex.Response;
                if (response.StatusCode ==
                    FtpStatusCode.ActionNotTakenFileUnavailable) {
                    exists = false; //Does not exist
                }
            }
            return exists;
        }
        public void UploadFile(string FullPathFilename) {
            /* Be sure to invoke UploadFile on an asynch thread, like on a backgroundWorker...
             
            private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {
            
                string username = "my_username";
                string password = "my_password";
                string host = "ftp://mywebsite.com";
                string myLocal = Path.GetDirectoryName(Application.ExecutablePath) + "\\myTextFile.txt";
                string myRemote = host + "/httpdocs/non_church/";        
                clsFTPclient client = new clsFTPclient(myRemote, username, password);            
                client.UploadFile(myLocal);
            }
             * 
             *                     ... or, rather than use a backgroundWorker...
             *                     
             * set up the same variables as above (username, password, host, myLocal, myRemote)
             * 
             * instantiate client as shown above, and then....
             * 
             * new System.Threading.Thread(() => client.UploadFile(Path.GetDirectoryName(Application.ExecutablePath) + 
                "\\myTextFile.txt")).Start();
             *  
             */
            string filename = Path.GetFileName(FullPathFilename);
            try {
                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();
            }
            catch (Exception ex) {
                updateErrorLog("Error in clsFTPclient.UploadFile()" + Environment.NewLine + ex.Message);
            }
            finally {
            }
        }
        private void updateErrorLog(string errorText) {
            string path = Path.GetDirectoryName(Application.ExecutablePath) + "\\clsFTPclientErrorLog.txt";           
            string msg = Environment.NewLine + Environment.NewLine;
            msg += DateTime.Now.ToString() + Environment.NewLine + errorText;
            File.AppendAllText(path, msg);                        
        }
    //next right-brace ends clsFTPclient
    }
    public class clsDirDetails {
        //a class to hold, in a convenient way, the details that are returned
        //by WebRequestMethods.Ftp.ListDirectoryDetails
        public enum DirectoryDetail { IsFileInDir, IsSubdirInDir };
        private DirectoryDetail dirMemberType; //is it a file or subdirectory?
        private string pathOrFilename; //path of subdir or filename if it's a file
        private string lastModified; //last time file got modified (applies to files only)
        private string unparsed; //the unparsed line that contains details
        private string ownerPermissions; //usually this will be rwx (read/write/execute)
        private bool ownerCanRead; //owner CAN or CANNOT read the specified dir/file
        private bool ownerCanWrite; //same as above, except WRITE rather than READ
        private bool ownerCanExecute; //same as above, except EXECUTE rather than WRITE
        //is it a file or a subdirectory?
        public DirectoryDetail DirMemberType {
            get { return dirMemberType; }
            set { dirMemberType = value; }
        }
        //owner permissions
        public string OwnerPermissions {
            get { return ownerPermissions; }
            set { ownerPermissions = value; }
        }
        //owner can read?
        public bool OwnerCanRead {
            get { return ownerCanRead; }
            set { ownerCanRead = value; }
        }
        //owner can write?
        public bool OwnerCanWrite {
            get { return ownerCanWrite; }
            set { ownerCanWrite = value; }
        }
        //owner can execute?
        public bool OwnerCanExecute {
            get { return OwnerCanExecute; }
            set { ownerCanExecute = value; }
        }
        //the full path
        public string PathOrFilename {
            get { return pathOrFilename; }
            set { pathOrFilename = value; }
        }
        //for files only...
        public string LastModified {
            get { return lastModified; }
            set { lastModified = value; }
        }
        //the unparsed line that contains details
        public string Unparsed {
            get { return unparsed; }
            set {  unparsed = value;
                
                //now that we know the full unparsed info, parse date from it and assign to lastModified
                string[] parts = unparsed.Split(' ');
                int dismissBelowThisElement = 0;
                string tmp = string.Empty;
                for (int i = 0; i < parts.GetUpperBound(0) + 1; i++) {
                    if (parts[i].Trim() == "4096") {
                        dismissBelowThisElement = i;
                        break;
                    }
                }
                for (int i = dismissBelowThisElement + 1; i < parts.GetUpperBound(0); i++) {
                    tmp += parts[i] + " ";
                }
                LastModified = tmp.Trim();
                //also parse out the subdir path or filename
                int j = unparsed.LastIndexOf(' ');
                PathOrFilename = unparsed.Substring(j + 1, unparsed.Length - j - 1);
                //assign DirMemberType
                if (unparsed.Substring(0, 1) == "d") {
                    DirMemberType = clsDirDetails.DirectoryDetail.IsSubdirInDir;
                }
                else {
                    DirMemberType = clsDirDetails.DirectoryDetail.IsFileInDir;
                }
                //assign OwnerPermissions
                ownerPermissions = unparsed.Substring(1, 3);
                if(ownerPermissions.Contains("r")){ ownerCanRead = true;}else{ownerCanRead = false;}
                if (ownerPermissions.Contains("w")) { ownerCanWrite = true; } else { ownerCanWrite = false; }
                if (ownerPermissions.Contains("x")) { ownerCanExecute = true; } else { ownerCanExecute = false; }
                
                //next right-brace ends set accessor of Unparsed property
            }
            //next right-brace ends Property Unparsed
        }
        
        //next right-brace ends clsDirDetails
    }
    //next right-brace ends namespace Kyrathasoft.NetUtilities.FTPclient
}
                                
                            Revision: 37180
                            
                                                            
                                    
                                        
Updated Code
                                    
                                    
                                                    
                        at January 3, 2011 09:24 by kyrathaba
                            
                            Updated Code
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) {
            _remoteHost = remoteHost;
            _remoteUser = remoteUser;
            _remotePass = remotePassword;
        }
        public List<string> DirectoryDetails(string subdirectory) {
            List<string> the_details = new List<string>();
            // Get the object used to communicate with the server.
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            // This example assumes the FTP site uses anonymous logon.
            request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            while (!reader.EndOfStream) {
                the_details.Add(reader.ReadLine());
            }
            return the_details;
        }
//List<string> files = client.DirectoryListing(""); //gives root listing
//List<string> files = client.DirectoryListing("//httpdocs"); //other dir 
        public 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);
            string result = string.Empty;
            while (!reader.EndOfStream) {
                result += reader.ReadLine() + Environment.NewLine;
            }
            reader.Close();
            response.Close();
            return result;
        }
        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();
        }
        public bool FileExistsAtThisURI(string fullFtpFilepath, string userName, string passWord) {
            bool exists = true;
            var request = (FtpWebRequest)WebRequest.Create(fullFtpFilepath);
            request.Credentials = new NetworkCredential(userName, passWord);
            request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
            try {
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            }
            catch (WebException ex) {
                FtpWebResponse response = (FtpWebResponse)ex.Response;
                if (response.StatusCode ==
                    FtpStatusCode.ActionNotTakenFileUnavailable) {
                    exists = false; //Does not exist
                }
            }
            return exists;
        }
        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();
        }
    }
                                
                            Revision: 37179
                            
                                                            
                                    
                                        
Updated Code
                                    
                                    
                                                    
                        at January 3, 2011 09:23 by kyrathaba
                            
                            Updated Code
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) {
            _remoteHost = remoteHost;
            _remoteUser = remoteUser;
            _remotePass = remotePassword;
        }
        public List<string> DirectoryDetails(string subdirectory) {
            List<string> the_details = new List<string>();
            // Get the object used to communicate with the server.
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(_remoteHost + subdirectory);
            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            // This example assumes the FTP site uses anonymous logon.
            request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            while (!reader.EndOfStream) {
                the_details.Add(reader.ReadLine());
            }
            return the_details;
        }
//List<string> files = client.DirectoryListing(""); //gives root listing
List<string> files = client.DirectoryListing("//httpdocs"); //other dir listing
        public 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);
            string result = string.Empty;
            while (!reader.EndOfStream) {
                result += reader.ReadLine() + Environment.NewLine;
            }
            reader.Close();
            response.Close();
            return result;
        }
        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();
        }
        public bool FileExistsAtThisURI(string fullFtpFilepath, string userName, string passWord) {
            bool exists = true;
            var request = (FtpWebRequest)WebRequest.Create(fullFtpFilepath);
            request.Credentials = new NetworkCredential(userName, passWord);
            request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
            try {
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            }
            catch (WebException ex) {
                FtpWebResponse response = (FtpWebResponse)ex.Response;
                if (response.StatusCode ==
                    FtpStatusCode.ActionNotTakenFileUnavailable) {
                    exists = false; //Does not exist
                }
            }
            return exists;
        }
        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();
        }
    }
                                
                            Revision: 37178
                            
                                                            
                                    
                                        
Updated Code
                                    
                                    
                                                    
                        at January 2, 2011 12:08 by kyrathaba
                            
                            Updated Code
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) {
            _remoteHost = remoteHost;
            _remoteUser = remoteUser;
            _remotePass = remotePassword;
        }
        public 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);
            string result = string.Empty;
            while (!reader.EndOfStream) {
                result += reader.ReadLine() + Environment.NewLine;
            }
            reader.Close();
            response.Close();
            return result;
        }
        public 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);
            string result = string.Empty; 
            while (!reader.EndOfStream) {
                result += reader.ReadLine() + Environment.NewLine;
            }
            reader.Close();
            response.Close();
            return result;
        }
        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();
        }
        public bool FileExistsAtThisURI(string fullFtpFilepath, string userName, string passWord) {
            bool exists = true;
            var request = (FtpWebRequest)WebRequest.Create(fullFtpFilepath);
            request.Credentials = new NetworkCredential(userName, passWord);
            request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
            try {
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            }
            catch (WebException ex) {
                FtpWebResponse response = (FtpWebResponse)ex.Response;
                if (response.StatusCode ==
                    FtpStatusCode.ActionNotTakenFileUnavailable) {
                    exists = false; //Does not exist
                }
            }
            return exists;
        }
        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();
        }
    }
                                
                            Revision: 37177
                            
                                                            
                                    
                                        
Initial Code
                                    
                                    
                                                            
                                    
                                        
Initial URL
                                    
                                    
                                                            
                                    
                                        
Initial Description
                                    
                                    
                                                            
                                    
                                        
Initial Title
                                    
                                    
                                                            
                                    
                                        
Initial Tags
                                    
                                    
                                                            
                                    
                                        
Initial Language
                                    
                                    
                                                    
                        at December 5, 2010 13:52 by kyrathaba
                            
                            Initial Code
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) {
            _remoteHost = remoteHost;
            _remoteUser = remoteUser;
            _remotePass = remotePassword;
        }
        public 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);
            string result = string.Empty;
            while (!reader.EndOfStream) {
                result += reader.ReadLine() + Environment.NewLine;
            }
            reader.Close();
            response.Close();
            return result;
        }
        public 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);
            string result = string.Empty; 
            while (!reader.EndOfStream) {
                result += reader.ReadLine() + Environment.NewLine;
            }
            reader.Close();
            response.Close();
            return result;
        }
        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();
        }
        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();
        }
    }
                                Initial URL
http://kyrathaba.dcmembers.com/errata/ftp.htm
Initial Description
Not extensively tested, but seems to work in my sample project. uses the class I posted here: http://www.snipplr.com/view/46669/minimist-c-errorlogging-class/
Initial Title
C# FTP Upload & Download
Initial Tags
download, c#
Initial Language
C#