在.NET中的FTP服务器上命令失败时会发生什么?

时间:2022-07-28 03:46:36

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.

服务器上的文件夹将存储在名为目录的ArrayList中。

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

存储在数据库中的目录ID将被加载到String []中,称为代理。

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)

目录将以ascendent顺序排序,类似地,代理按照ascendent顺序排序(这两个都是此项目中的数字,因此它们按数字排序)

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.

如果服务器和存储目录列表中也存在目录,则将删除不推荐使用的文件。服务器上相应目录中的文件称为文件,存储在数据库中的文件存储在名为dbFiles的String []中。

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.

例如i = 500和(我不知道为什么)当i = 100时,为命令捕获服务器错误并且我回落到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 ?

当我100岁时,j会回到这个状态吗?

How can I prevent this dropback?

如何防止此回退?

3 个解决方案

#1


3  

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:

你应该重构你的代码,以便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);
  }
}

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.

然后你只需要为ftpGetListing,ftpDeleteDirectories,ftpCreateDirectories和ftpDeleteFile实现非常简单的函数。哦是的和一些简单的数组操作函数,如:getElementsInBothArrays和getElementsOnlyInFitstArray。

#2


1  

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

它不是J正在被重置,而是它没有被增加。下面是一个模拟控制流程的控制台程序。

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).

控制台的输出变化很大,具体取决于是否//抛出新的InvalidOperationException被注释掉。这就在你的附近(!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();


    }
}

#3


1  

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

当我们只打开responseStream时

response.Close();

when a responseStream was not opened.

什么时候没有打开responseStream。

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

我不确定这个问题的原因,但我认为C#正在为我的源代码做一个分叉。

#1


3  

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:

你应该重构你的代码,以便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);
  }
}

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.

然后你只需要为ftpGetListing,ftpDeleteDirectories,ftpCreateDirectories和ftpDeleteFile实现非常简单的函数。哦是的和一些简单的数组操作函数,如:getElementsInBothArrays和getElementsOnlyInFitstArray。

#2


1  

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

它不是J正在被重置,而是它没有被增加。下面是一个模拟控制流程的控制台程序。

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).

控制台的输出变化很大,具体取决于是否//抛出新的InvalidOperationException被注释掉。这就在你的附近(!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();


    }
}

#3


1  

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

当我们只打开responseStream时

response.Close();

when a responseStream was not opened.

什么时候没有打开responseStream。

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

我不确定这个问题的原因,但我认为C#正在为我的源代码做一个分叉。