2010-09-14 30 views
1

我有這個源代碼:當.NET中的FTP服務器上的命令失敗時會發生什麼?

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 []中。

目錄將在方興未艾順序進行排序,同樣地,試劑在方興未艾順序(兩者都是在這個項目中的數字,所以他們用數字排序)

如果服務器上存在的目錄,但排序它不會存在於數據庫中,它將被刪除(首先刪除它的所有文件,然後文件夾本身也會被刪除)

如果一個目錄在服務器上不存在,但存在於存儲的目錄列表中,它將在服務器上創建。

如果服務器和存儲的目錄列表中也存在目錄,則不推薦使用的文件將被刪除。服務器上相應目錄中的文件稱爲文件,存儲在數據庫中的文件存儲在名爲dbFiles的String[]中。

該函數實質上創建了要創建的文件夾,刪除了要刪除的文件夾並刪除了要刪除的文件並且工作正常。但是,我注意到在某些情況下,當發生服務器錯誤時,索引會下降,我不知道可能是什麼原因。

例如I = 500(我不知道爲什麼)的服務器錯誤釣到的命令時,I = 100,爲的情況下,我回落到100

我的問題是:爲什麼每當先前發生的錯誤被捕獲時,我的索引就會回落?

當我100歲時,j會回落到狀態嗎?

如何防止此回退?

+0

「服務器錯誤被捕獲」...它是什麼? – 2010-09-14 21:44:51

+2

你的代碼有很多問題:1)永遠不要發現異常並忽略它。它試圖告訴你一些你需要知道的東西。 2)'FtpWebResponse','Stream'和'StreamReader'都實現了'IDisposable',所以你需要在'using'塊中使用它們。 – 2010-09-14 21:56:15

+0

@John Saunders:謝謝您的寶貴意見。我的答案:1)首先他們沒有被忽略,我在MessageBox-es中調試時顯示它們以查找可能的錯誤。 2)我不知道這一點,謝謝你的信息,我會upvote你,如果我有權利 – 2010-09-14 23:23:35

回答

1

我發現瞭解決方案。

首先,這必須設置爲避免這個問題:

request.KeepAlive = false; 

其次,在抓這必須包括:

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

當我們有一個responseStream打開,只

response.Close(); 

當一個responseStream沒有打開。

我不確定這個問題的原因,但我認爲C#正在爲我的源代碼做一個分支。

1

它不是J被重置,而是它沒有被增加。以下是一個模擬您的控制流程的控制檯程序。

對控制檯的輸出變化很大,取決於如果/ /拋出新的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(); 


    } 
} 
+0

這是完成源代碼的想法,但是我只會在我知道我的問題的答案時最終確定它。例如,關閉響應的位置取決於答案。 – 2010-09-14 23:25:05

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,ftpDeleteDirectories,ftpCreateDirectoriesftpDeleteFile實現真正簡單的功能。噢,還有一些簡單的數組操作函數,如:getElementsInBothArraysgetElementsOnlyInFitstArray

+0

這也是一個富有洞察力的評論,但我仍然不知道爲什麼我的索引從500重回100. – 2010-09-14 23:26:35

+1

+1爲他重構。 – 2010-09-15 04:11:42

相關問題