0

My program has several times where it queries an FTP server to read and upload information. How can I combine all these into one FTP class to handle everything?

    private static void UploadToFTP(string[] FTPSettings)
    {
        try
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(FTPSettings[0]);
            request.Method = WebRequestMethods.Ftp.MakeDirectory;

            request.Credentials = new NetworkCredential(FTPSettings[1], FTPSettings[2]);

            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
        }
        catch
        {
        }

        try 
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(FTPSettings[0] + Path.GetFileName(file));
            request.Method = WebRequestMethods.Ftp.UploadFile;

            request.Credentials = new NetworkCredential(FTPSettings[1], FTPSettings[2]);

            StreamReader source = new StreamReader(file);
            byte[] fileContents = Encoding.UTF8.GetBytes(source.ReadToEnd());
            source.Close();
            request.ContentLength = fileContents.Length;

            Stream requestStream = request.GetRequestStream();
            requestStream.Write(fileContents, 0, fileContents.Length);
            requestStream.Close();

            FtpWebResponse response = (FtpWebResponse)request.GetResponse();

            response.Close();

            RegenLog();
        }
        catch (Exception e)
        {
            File.AppendAllText(file, string.Format("{0}{0}Upload Failed - ({2}) - {1}{0}", nl, System.DateTime.Now, e.Message.ToString()));
        }
    }

    private static void CheckBlacklist(string[] FTPSettings)
    {
        try
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(FTPSettings[0] + "blacklist.txt");
            request.Credentials = new NetworkCredential(FTPSettings[1], FTPSettings[2]);

            using (WebResponse response = request.GetResponse())
            {
                using (Stream stream = response.GetResponseStream())
                {
                    using (TextReader reader = new StreamReader(stream))
                    {
                        string blacklist = reader.ReadToEnd();

                        if (blacklist.Contains(Environment.UserName))
                        {
                            File.AppendAllText(file, string.Format("{0}{0}Logger terminated - ({2}) - {1}{0}", nl, System.DateTime.Now, "Blacklisted"));
                            uninstall = true;
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            File.AppendAllText(file, string.Format("{0}{0}FTP Error - ({2}) - {1}{0}", nl, System.DateTime.Now, e.Message.ToString()));
        }
    }

    private static void CheckUpdate(string[] FTPSettings)
    {
        try
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(FTPSettings[0] + "update.txt");
            request.Credentials = new NetworkCredential(FTPSettings[1], FTPSettings[2]);

            using (WebResponse response = request.GetResponse())
            {
                using (Stream stream = response.GetResponseStream())
                {
                    using (TextReader reader = new StreamReader(stream))
                    {
                        string newVersion = reader.ReadToEnd();

                        if (newVersion != version)
                        {
                            update = true;
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            File.AppendAllText(file, string.Format("{0}{0}FTP Error - ({2}) - {1}{0}", nl, System.DateTime.Now, e.Message.ToString()));
        }
    }

I know my code is also a bit inconsistent and messy, however this is my first time working with FTP in C#. Please give any advice you have!

rshea0
  • 11,769
  • 9
  • 27
  • 40

3 Answers3

5

An ideal option would be to use a "manager" type of class, implementing the IDisposable interface.

Let it have some internal fields (which get initialized in the constructor) and one connection (also initialized in the constructor) Every method should check if the connection is alive and, if it is, perform the operation; otherwise, try to restore it then throw an exception.

In Dispose method, you close the connection.

This should give you an idea on how it may look:

// Partial class declaration
class FTPManager : IDisposable
{
    void Dispose();
    FTPManager(string host, string username, string password)
    void UploadFile(string remoteDir, string localfile);
    void CreateDirectory(string remotePath);
    void DeleteFile(string remotePath);
}

// and here I use it:
void Main()
{
    using (var manager = new FTPManager("ftp.somehosting.org","login","password")) {
        manager.CreateDirectory("/newfolder/");
        manager.UploadFile("/newfolder/","C:\\Somefile.txt");
        manager.DeleteFile("/newfolder/anotherfile.txt");
    }
}
DarkWanderer
  • 8,739
  • 1
  • 25
  • 56
1

You might want to look at the WinSCP library. WinSCP has a lot of features and supports more secure protocols than (inherently unsecure FTP). Recent releases even feature a scripting mechanism.

Axel Kemper
  • 10,544
  • 2
  • 31
  • 54
0

You should use other FTP .NET library (there is a number of them over the internet, free ones and commercial as well), which allow to do all the commands in one connection. That would work much faster.

Nickolay Olshevsky
  • 13,706
  • 1
  • 34
  • 48