2013-06-23 6 views
0

Я сделал метод, который может сканировать ftp-сервер. Он имеет две части в выражении if ... else. Первая часть в if выполняется, когда список каталогов равен 0, и отделяет папки от файлов (и помещает их в этот список). Затем (потому что список больше не пуст) должно выполняться инструкция else. Он имеет петлю foreach, которая проверяет все элементы списка и объединяет их с адресом ftp и просматривает эту папку. И вот проблема. Похоже, он превращается в бесконечный цикл. Я только хочу проверить папки на сервере и разбить цикл, но похоже, что я не могу найти полезное решение.Как я могу исправить следующий метод?

Вот код:

internal void ListFilesOnServer() 
     { 
      ArrayList files = new ArrayList(); 
      if (directories.Count == 0) 
      { 
       try 
       { 
        FtpWebRequest ftpwrq = (FtpWebRequest)WebRequest.Create(server); 
        ftpwrq.Credentials = new NetworkCredential(user, passw); 
        ftpwrq.Method = WebRequestMethods.Ftp.ListDirectory; 
        ftpwrq.KeepAlive = false; 
        FtpWebResponse fresponse = (FtpWebResponse)ftpwrq.GetResponse(); 
        StreamReader sr = new StreamReader(fresponse.GetResponseStream()); 
        string temp = ""; 
        while ((temp = sr.ReadLine()) != null) 
        { 
         files.Add(temp); 
        } 
        temp = String.Empty; 
        sr.Close(); 
        fresponse.Close(); 
        DirOrFile(files); 
       } 
       catch (Exception e) 
       { 
        MessageBox.Show(e.Message); 
       } 
      } 
      else 
      { 
       foreach (string file in directories.ToArray()) 
       { 
        try 
        { 
         FtpWebRequest ftpwrq = (FtpWebRequest)WebRequest.Create(server+"/"+file); 
         ftpwrq.Credentials = new NetworkCredential(user, passw); 
         ftpwrq.Method = WebRequestMethods.Ftp.ListDirectory; 
         ftpwrq.KeepAlive = false; 
         FtpWebResponse fresponse = (FtpWebResponse)ftpwrq.GetResponse(); 
         StreamReader sr = new StreamReader(fresponse.GetResponseStream()); 
         string temp = ""; 
         while ((temp = sr.ReadLine()) != null) 
         { 
          files.Add(temp); 
         } 
         temp = String.Empty; 
         sr.Close(); 
         fresponse.Close(); 
         DirOrFile(files); 
        } 
        catch(ArgumentException) 
        { 

        } 
        catch (Exception e) 
        { 
         MessageBox.Show(e.Message); 
        } 
       } 
      } 
      ListFilesOnServer(); 
     } 
+0

Куда он застревает? вы проверяли его с помощью контрольных точек? – Shaharyar

+0

Операция else не запускается после if, просто имеет код follow.an if, если вы хотите, чтобы это произошло (нет) – Sayse

+0

Вы застреваете в цикле, потому что вы вызываете функцию рекурсивно, даже не устанавливая каталоги – Sayse

ответ

0

Бесконечный цикл, потому что вы не имеете способ вырваться из рекурсии.

Шаблон для рекурсии выглядит следующим образом

MyRecursiveMethod() 
{ 
    if (conditions) 
    { 
    } 
    else 
    { 
     MyRecursiveMethod() 
    } 
} 

Вот как я мог бы идти о перезаписи этого кода, чтобы заставить его работать на вас.

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Net; 
using System.Security; 
using System.Windows.Forms; 

namespace ConsoleApplication5 
{ 
    public class FtpTest 
    { 
     string server = "servier/"; 
     string user = "user"; 
     SecureString passw = new SecureString(); 

     public List<string> GetFilesOnServer() 
     { 
      return GetFilesOnServer(server); 
     } 

     public List<string> GetFilesOnServer(string dir) 
     { 
      var root = GetDirectoryContents(dir); 
      var files = new List<string>(); 

      foreach (string name in root) 
      { 
       var path = GetFullPath(dir, name); 
       if (IsDirectory(name)) 
       { 
        var subFiles = GetFilesOnServer(path); 
        files.AddRange(subFiles); 
       } 
       else 
       { 
        files.Add(path); 
       } 
      } 

      return files; 
     } 

     public List<string> GetDirectoryContents(string dir) 
     { 
      var files = new List<string>(); 

      try 
      { 
       var ftpwrq = (FtpWebRequest)WebRequest.Create(dir); 
       ftpwrq.Credentials = new NetworkCredential(user, passw); 
       ftpwrq.Method = WebRequestMethods.Ftp.ListDirectory; 
       ftpwrq.KeepAlive = false; 
       var fresponse = (FtpWebResponse)ftpwrq.GetResponse(); 
       var sr = new StreamReader(fresponse.GetResponseStream()); 
       string fileName = ""; 
       while ((fileName = sr.ReadLine()) != null) 
       { 
        files.Add(fileName); 
       } 
       sr.Close(); 
       fresponse.Close(); 
       return files; 
      } 
      catch (ArgumentException) 
      { 

      } 
      catch (Exception e) 
      { 
       MessageBox.Show(e.Message); 
      } 

      return files; 
     } 

     public static string GetFullPath(string dir, string file) 
     { 
      string path = dir; 
      if (!path.EndsWith("/")) 
       path += "/"; 
      path += file; 
      return path; 
     } 

     public static bool IsDirectory(string name) 
     { 
      return name.IndexOf(".") > 0; 
     } 
    } 
} 

Обратите внимание, что я только рекурсивный вызов в GetFilesOnServer, если элемент извлекается является каталогом. Я также реорганизовал код, который захватывает содержимое на FTP-сервере в нерекурсивный метод.

Надеюсь, это поможет вам.