Что происходит при сбое команды на FTP-сервере в .NET? - PullRequest
1 голос
/ 15 сентября 2010

У меня есть этот исходный код:

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");

}

Используется для удаления устаревших каталогов и файлов с сервера.У меня есть основная папка, где все подпапки являются числами, а все подпапки содержат только файлы (нет подпапок подпапок)

Папки на сервере будут храниться в ArrayList, называемом каталогами.

Идентификаторы каталогов, хранящиеся в базе данных, будут загружены в String [], называемую агентами.

каталоги будут отсортированы в порядке возрастания, аналогично, агенты отсортированы в порядке возрастания (оба они являются числами).в этом проекте они упорядочены по номерам)

Если каталог существует на сервере, но не существует в базе данных, он будет удален (сначала удаляются все его файлы, затем папкасама также будет удалена)

Если каталог не существует на сервере, но существует в списке сохраненных каталогов, он будет создан на сервере.

Если каталог существует насервер и в списке сохраненных каталогов, устаревшие файлы будут удалены.Файлы в соответствующем каталоге на сервере называются файлами, а файлы, хранящиеся в базе данных, хранятся в String[], называемом dbFiles.

Эта функция, по сути, создает папки, которые нужно создать, удаляет папку вбыть удален и удаляет файлы, которые будут удалены, и это работает.Тем не менее, я заметил, что в некоторых случаях, когда происходит ошибка сервера, индекс падает обратно, и мне интересно, что может быть причиной.

Например, я = 500 и (я не знаю почему) ошибка сервераперехватывается для команды, когда i = 100 имело место, и я возвращался к 100.

Мой вопрос: почему мой индекс возвращается к предыдущему разу, когда была обнаружена ранее произошедшая ошибка?

Будетj вернуться в состояние, когда мне было 100 лет?

Как я могу предотвратить этот откат?

Ответы [ 3 ]

3 голосов
/ 15 сентября 2010

Вы должны реорганизовать свой код так, чтобы команды ftp были в функциях, и вместо того, чтобы копировать / вставлять эти команды ftp повсюду, у вас есть такой поток:

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);
  }
}

Тогда вам просто нужно реализовать действительно простые функции для ftpGetListing, ftpDeleteDirectories, ftpCreateDirectories и ftpDeleteFile. О да, и некоторые простые функции манипулирования массивами, такие как: getElementsInBothArrays и getElementsOnlyInFitstArray.

1 голос
/ 20 сентября 2010

Я выяснил, каково решение.

Прежде всего, это должно быть установлено, чтобы избежать проблемы:

request.KeepAlive = false;

Во-вторых, в улове это должно быть включено:

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

когда у нас откроется responseStream и только

response.Close();

когда responseStream не был открыт.

Я не уверен в причине этой проблемы, но я думаю, что C # делает форк для моего исходного кода.

1 голос
/ 15 сентября 2010

Дело не в том, что J сбрасывается, а в том, что оно не увеличивается.Ниже представлена ​​консольная программа, которая имитирует поток управления.

Вывод на консоль сильно меняется в зависимости от того, // закинут ли новый InvalidOperationException или нет.Это недалеко от вашего времени (! Reader.EndOfStream).

Честно говоря, этот процесс довольно сложный.Вы могли бы быть хорошо обслужены, если бы разбили этот метод на кусочки размером с укус.

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();


    }
}
...