views:

90

answers:

3

I have this source code:

public static void FTP_SERVER()
{
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/");
    request.Method = WebRequestMethods.Ftp.ListDirectory;
    request.Credentials = new NetworkCredential("myusername", "mypassword");
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
    Stream responseStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(responseStream);
    ArrayList directories = new ArrayList();
    while (!reader.EndOfStream)
    {
        String directory = reader.ReadLine();
        int i = 0;
        for (i = 0; i < directories.Count && Convert.ToInt32(directory) > Convert.ToInt32(directories[i] + ""); i++);
        directories.Insert(i, directory);
    }
    String[] agents = Crawler.CrawlerDbUtils.getAllAgentIDs();

    reader.Close();
    response.Close();
    int j = 0;
    for (int i = 0; i < directories.Count; i++)
    {
        try
        {
            while ((j < agents.Length) && (Convert.ToInt32(agents[j]) < Convert.ToInt32(directories[i] + "")))
            {
                try
                {
                    request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + agents[j]);
                    request.Method = WebRequestMethods.Ftp.MakeDirectory;
                    request.Credentials = new NetworkCredential("myusername", "mypassword");
                    response = (FtpWebResponse)request.GetResponse();
                    responseStream = response.GetResponseStream();
                    response.Close();
                }
                catch (Exception exception)
                { }
                j++;
            }
            if (Convert.ToInt32(agents[j]) == Convert.ToInt32(directories[i] + ""))
            {
                request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + directories[i] + "/");
                request.Method = WebRequestMethods.Ftp.ListDirectory;
                request.Credentials = new NetworkCredential("myusername", "mypassword");
                response = (FtpWebResponse)request.GetResponse();
                responseStream = response.GetResponseStream();
                reader = new StreamReader(responseStream);
                ArrayList files = new ArrayList();
                while (!reader.EndOfStream)
                {
                    String file = reader.ReadLine();
                    int q = 0;
                    for (q = 0; q < files.Count && file.CompareTo(files[q] + "") > 0; q++) ;
                    files.Insert(q, file);
                }
                reader.Close();
                response.Close();
                String[] dbFiles = Crawler.CrawlerDbUtils.getAllPictures(directories[i] + "");
                int r = 0;
                for (int q = 0; q < files.Count; q++)
                {
                    while ((r < dbFiles.Length) && ((dbFiles[r] + "").CompareTo(files[q] + "") < 0))
                    {
                        r++;
                    }
                    try
                    {
                        if ((r >= dbFiles.Length) || ((dbFiles[r] + "").Equals(files[q]) == false))
                        {
                            request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + directories[i] + "/" + files[q]);
                            request.Method = WebRequestMethods.Ftp.DeleteFile;
                            request.Credentials = new NetworkCredential("myusername", "mypassword");
                            response = (FtpWebResponse)request.GetResponse();
                            responseStream = response.GetResponseStream();
                            response.Close();
                        }
                    }
                    catch (Exception exception)
                    { }
                }
                j++;
            }
            else
            {
                request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + directories[i] + "/");
                request.Method = WebRequestMethods.Ftp.ListDirectory;
                request.Credentials = new NetworkCredential("myusername", "mypassword");
                response = (FtpWebResponse)request.GetResponse();
                responseStream = response.GetResponseStream();
                reader = new StreamReader(responseStream);
                ArrayList files = new ArrayList();
                while (!reader.EndOfStream)
                {
                    files.Add(reader.ReadLine());
                }
                reader.Close();
                response.Close();
                for (int k = 0; k < files.Count; k++)
                {
                    request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + directories[i] + "/" + files[k]);
                    request.Method = WebRequestMethods.Ftp.DeleteFile;
                    request.Credentials = new NetworkCredential("myusername", "mypassword");
                    response = (FtpWebResponse)request.GetResponse();
                    responseStream = response.GetResponseStream();
                    response.Close();
                }
                request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + directories[i] + "/");
                request.Method = WebRequestMethods.Ftp.RemoveDirectory;
                request.Credentials = new NetworkCredential("myusername", "mypassword");
                response = (FtpWebResponse)request.GetResponse();
                responseStream = response.GetResponseStream();
                response.Close();
            }
        }
        catch (Exception exception)
        {
        }
    }
    while (j < agents.Length)
    {
        try
        {
            request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + agents[j] + "/");
            request.Method = WebRequestMethods.Ftp.MakeDirectory;
            request.Credentials = new NetworkCredential("myusername", "mypassword");
            response = (FtpWebResponse)request.GetResponse();
            responseStream = response.GetResponseStream();
            response.Close();
        }
        catch (Exception exception)
        { }
        j++;
    }
    MessageBox.Show("DONE");

}

It's used to delete deprecated directories and files from a server. I have a mainfolder, where all the subfolders are numbers and all of the subfolders contain only files (there are no subfolders of subfolders)

The folders on the server will be stored in an ArrayList called directories.

The directory ID's stored in the database will be loaded into the String[] called agents.

directories will be sorted in ascendent order, similarly, the agents are sorted in ascendent order (both of them are numbers in this project, so they are ordered numerically)

If a directory exists on the server, but it doesn't exist in the database, it will be deleted (First all of its files are deleted, then the folder itself will be deleted too)

If a directory doesn't exist on the server, but exists in the stored directory list, it will be created on the server.

If a directory exists on the server and in the stored directory list too, deprecated files will be deleted. The files in the respective directory on the server is called files, and the files stored in the database are stored in a String[] called dbFiles.

This function essentially creates the folders to be created, deletes the folder to be deleted and deletes the files to be deleted and it works. However, I noticed that in some cases when a server error occurs, the index drops back and I wonder what can be the cause.

For example i = 500 and (I don't know why) a server error is catched for a command when i = 100 was the case and i drops back to 100.

My question is: why does my index drop back whenever a previously happened error was catched?

Will j drop back to the state when i was 100 ?

How can I prevent this dropback?

A: 

Its not that J is being reset, its that its not being incremented. Below is a console program that simulates your control flow.

The output to the console changes greatly depending on if //throw new InvalidOperationException is commented out or not. This is near your while(!reader.EndOfStream).

Honestly this flow is pretty complex. You might be well served if broke up some this method into bite sized pieces.

class Program
{
    static void Main(string[] args)
    {
        int agentCount = 1000;
        int directoriesCount =100;
        int fileCount = 100;
        int dbFilesCount = 100;
        int j = 0;
        for (int i = 0; i < directoriesCount; i++)
        {
            Console.WriteLine("I : {0}", i);
            try
            {
                while ((j < agentCount))
                {
                    try
                    {

                    }
                    catch (Exception exception)
                    { }
                    j++;
                    Console.WriteLine("J : {0}", j);
                }
                if (true)
                {

                    //throw new InvalidOperationException("Some error"); UnComment and see
                    while (false)
                    {

                    }


                    int r = 0;
                    for (int q = 0; q < fileCount; q++)
                    {
                        while ((r < dbFilesCount) )
                        {
                            r++;
                        }
                        try
                        {
                            if ((r >= dbFilesCount))
                            {

                            }
                        }
                        catch (Exception exception)
                        { }
                    }
                    j++;
                    Console.WriteLine("J : {0}", j);
                }
                else
                {

                    while (false)
                    {

                    }

                    for (int k = 0; k < fileCount; k++)
                    {

                    }

                }
            }
            catch (Exception exception)
            {
            }
        }
        while (j < agentCount)
        {
            try
            {

            }
            catch (Exception exception)
            { }
            j++;
            Console.WriteLine("J : {0}", j);
        }
        Console.WriteLine("Done");
        Console.ReadLine();


    }
}
Conrad Frix
That's the idea of finalizing the source code, but I will only finalize it when I know the answer for my question. For instance, the location of closing the response depends on the answer.
Lajos Arpad
+1  A: 

You should refactor your code so that the ftp commands are in functions and instead of copy/pasting those ftp commands everywhere, you have some flow like this:

String[] directories = ftpGetListing("ftp://myurl.com/mainfolder/");
String[] agents = Crawler.CrawlerDbUtils.getAllAgentIDs();

String[] combinedDirectories = getElementsInBothArray(directories, agents);
String[] serverOnlyDirectories = getElementsOnlyInFirstArray(directories, agents);
String[] agentOnlyDirectories = getElementsOnlyInFirstArray(agents, directories);

// step 1: delete all server only directories
ftpDeleteDirectories("ftp://myurl.com/mainfolder/", serverOnlyDirectories);

// step 2: create all agent only directories
ftpCreateDirectories("ftp://myurl.com/mainfolder/", agentOnlyDirectories);

// step 3: depricate all files
foreach(String dir in combinedDirectories)
{
  String ftpDir = "ftp://myurl.com/mainfolder/" + dir + "/";
  String[] serverFiles = ftpGetListing(ftpDir);
  String[] agentFiles = Crawler.CrawlerDbUtils.getAllPictures(dir);

  String[] serverOnlyFiles = getElementsOnlyInFirstArray(serverFiles, agentFiles);

  foreach(String file in serverOnlyFiles)
  {
    ftpDeleteFile(ftpDir + file);
  }
}

Then you just have to implement really simple functions for ftpGetListing, ftpDeleteDirectories, ftpCreateDirectories, and ftpDeleteFile. Oh yeah and some simple array manipulation functions like: getElementsInBothArrays and getElementsOnlyInFitstArray.

Mohamed Nuur
This is also an insightful comment, but I still don't know why does my i index get back to 100 from 500.
Lajos Arpad
+1 for refactoring it for him.
Conrad Frix
Thanks Conrad!!
Mohamed Nuur
A: 

Hello, I've found out what is the solution.

First of all, this must be set to avoid the problem:

request.KeepAlive = false;

Secondly, in the catch this must be included:

response.Close();
responseStream.Close();

when we have a responseStream opened and only

response.Close();

when a responseStream was not opened.

I'm not sure about the reason of this problem, but I think C# is making a fork for my source code.

Lajos Arpad