1

私はこのソースコードを持っています:

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 に格納されます。

データベースに保存されているディレクトリ ID は、エージェントと呼ばれる String[] にロードされます。

ディレクトリは昇順でソートされ、同様に、エージェントは昇順でソートされます (このプロジェクトではどちらも番号であるため、番号順に並べられています)。

ディレクトリがサーバーに存在するが、データベースに存在しない場合、そのディレクトリは削除されます (最初にすべてのファイルが削除され、次にフォルダ自体も削除されます)。

ディレクトリがサーバー上に存在しないが、格納されたディレクトリ リストに存在する場合、そのディレクトリはサーバー上に作成されます。

ディレクトリがサーバー上に存在し、保存されたディレクトリ リストにも存在する場合、非推奨のファイルは削除されます。サーバー上のそれぞれのディレクトリ内のファイルはファイルと呼ばれ、データベースに保存されているファイルはString[]dbFiles という名前で保存されます。

この機能は基本的に、作成するフォルダーを作成し、削除するフォルダーを削除し、削除するファイルを削除し、機能します。しかし、サーバーエラーが発生した場合、インデックスが元に戻ってしまうことがあり、何が原因なのだろうかと気付きました。

たとえば、i = 500 の場合 (理由はわかりません)、i = 100 の場合にコマンドでサーバー エラーがキャッチされ、i が 100 に戻ります。

私の質問は、以前に発生したエラーがキャッチされるたびにインデックスがドロップバックするのはなぜですか?

j は、私が 100 歳のときの状態に戻りますか?

このドロップバックを防ぐにはどうすればよいですか?

4

3 に答える 3

3

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次に、 、ftpDeleteDirectoriesftpCreateDirectories、およびの非常に単純な関数を実装する必要がありftpDeleteFileます。そうそう、いくつかの単純な配列操作関数:getElementsInBothArraysgetElementsOnlyInFitstArray.

于 2010-09-14T22:03:27.753 に答える
1

Jがリセットされているのではなく、インクリメントされていません。以下は、制御フローをシミュレートするコンソール プログラムです。

//throw new InvalidOperationException がコメントアウトされているかどうかで、コンソールへの出力が大きく変わります。これは while(!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();


    }
}
于 2010-09-14T21:53:00.080 に答える
1

私は解決策が何であるかを見つけました。

まず第一に、これを設定して問題を回避する必要があります。

request.KeepAlive = false;

次に、catch にこれを含める必要があります。

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

responseStream を開いたときにのみ

response.Close();

responseStream が開かれなかったとき。

この問題の理由はよくわかりませんが、C# がソース コードのフォークを作成していると思います。

于 2010-09-19T20:11:24.397 に答える