2012-02-06 18 views
2

嗨,感谢您的期待!如何为给定FTP地址的所有文件提取文件位置(路径和文件名)?

背景

我需要拉所有文件的文件位置(路径和文件名)在给定的FTP地址。

对于映射的网络或本地驱动器上的文件,该代码将工作:

foreach(string fileName f in Directory.GetFiles("C\\:SomeDirectory"), "*.*", 
            SearchOption.AllDirectories) 
{ 
    //do stuff with each file found 
} 

但这不会工作在FTP连接。我已经找到this MS documentation,其中涵盖了建立一个FTPWebRequest,但它并没有告诉我如何遍历每个找到的文件(在所有的嵌套目录中)。

我在表单应用中使用C#。

问题

如何做到这一点:

foreach(string fileName f in Directory.GetFiles("C\\:SomeDirectory"), "*.*", 
             SearchOption.AllDirectories) 
    { 
     //do stuff with each file found 
    } 

与FTP连接?

非常感谢!

更新/最终答案

特别感谢@sunk为了实现这一目标。我对他的代码做了一个小小的修改,使它完全递归,以便它可以钻入嵌套的文件夹。这里是最终代码:

 //A list that holds all file locations in all folders of a given FTP address: 
     List<string> fnl= new List<string>(); 

     //A string to hold the base FTP address: 
     string ftpBase = "ftp://[SOME FTP ADDRESS]"; 

     //A button-click event. Can be a stand alone method as well 
     private void GetFileLocations(object sender, EventArgs e) 
     { 
      //Get the file names from the FTP location: 
      DownloadFileNames(ftpBase); 

      //Once 'DownloadFileNames' has run, we have populated 'fnl' 
      foreach(var f in fnl) 
      { 
       //do stuff 
      }   
     } 

     //Gets all files in a given FTP address. RECURSIVE METHOD: 
     public void DownloadFileNames(string ftpAddress) 
     { 
      string uri = ftpAddress; 
      FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri); 
      reqFTP.Credentials = new NetworkCredential("pella", "PellaWA01!"); 
      reqFTP.EnableSsl = false; 
      reqFTP.KeepAlive = false; 
      reqFTP.UseBinary = true; 
      reqFTP.UsePassive = true; 
      reqFTP.Method = WebRequestMethods.Ftp.ListDirectory; 
      FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 
      Stream responseStream = response.GetResponseStream(); 
      List<string> files = new List<string>(); 
      StreamReader reader = new StreamReader(responseStream); 
      while (!reader.EndOfStream) 
       files.Add(reader.ReadLine()); 
      reader.Close(); 
      responseStream.Dispose(); 

      //Loop through the resulting file names. 
      foreach (var fileName in files) 
      { 
       var parentDirectory = ""; 

       //If the filename has an extension, then it actually is 
       //a file and should be added to 'fnl'.    
       if (fileName.IndexOf(".") > 0) 
       { 
        fnl.Add(ftpAddress.Replace("ftp://pella.upload.akamai.com/140607/pella/",    "http://media.pella.com/") + fileName); 
       } 
       else 
       { 
       //If the filename has no extension, then it is just a folder. 
       //Run this method again as a recursion of the original: 
        parentDirectory += fileName + "/"; 
        try 
        { 
         DownloadFileNames(ftpAddress + parentDirectory); 
        } 
        catch (Exception) 
        { 
         //throw; 
        } 
       } 
      } 
     } 
+0

你已经采取了看的FtpWebRequest - http://msdn.microsoft.com/en-我们/图书馆/ system.net.ftpwebrequest.aspx – 2012-02-06 19:25:45

+0

在我看来,你链接的例子给你你需要的一切。少了什么东西? – vlad 2012-02-06 19:27:52

+0

@vlad OP想知道如何迭代返回的文件/目录(以及对它们做什么)。 – 2012-02-06 19:29:15

回答

2

首先发现,你必须得到的文件名称中使用的FtpWebRequest你的机器上本地。

WebRequestMethods.Ftp.ListDirectory; 

然后使用foreach {};

下面是代码: -

public List<string> DownloadFileNames() 
     { 
       string uri = "ftp://" + ftpServerIP + "/"; 
       FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri); 
       reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 
       reqFTP.EnableSsl = true; 
       reqFTP.KeepAlive = false; 
       reqFTP.UseBinary = true; 
       reqFTP.UsePassive = Settings.UsePassive; 
       reqFTP.Method = WebRequestMethods.Ftp.ListDirectory; 
       ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications); 
       FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 
       Stream responseStream = response.GetResponseStream(); 
       List<string> files = new List<string>(); 
       StreamReader reader = new StreamReader(responseStream); 
       while (!reader.EndOfStream) 
        files.Add(reader.ReadLine()); 
       reader.Close(); 
       responseStream.Dispose(); 
       return files; 
     } 

现在你有名单: -

List<string> FileNameList = DownloadFileNames(); 
foreach (var fileName in FileNameList) 
{ 

} 
+0

你应该看看'using'关键字 – 2012-02-06 19:55:59

+0

谢谢沉没。这看起来有希望。但是有一个问题 - 我有很多嵌套的文件夹。是否有一个命令可以让我返回所有嵌套文件夹中的文件,或者我需要为此编写一些代码?谢谢! – 2012-02-06 20:10:49

+0

一个建议。只是写一个超载的方法**公开名单 DownloadFiles(字符串FileName)**。从你的foreach循环再次调用它,并连接** uri **中的参数** Filename **。像** string uri =“ftp://”+ ftpServerIP +“/”+ FileName +“/”**; – sunk 2012-02-06 20:46:46

1

该示例中使用的ListDirectoryDe​​tails命令只是返回一个字符串。您将不得不手动解析它以构建文件和子目录的列表。

1

http://social.msdn.microsoft.com/Forums/en/ncl/thread/079fb811-3c55-4959-85c4-677e4b20bea3

string[] files = GetFileList(); 
    foreach (string file in files) 
    { 
     Download(file); 
    } 

    public string[] GetFileList() 
    { 
     string[] downloadFiles; 
     StringBuilder result = new StringBuilder(); 
     WebResponse response = null; 
     StreamReader reader = null; 
     try 
     { 
      FtpWebRequest reqFTP; 
      reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/")); 
      reqFTP.UseBinary = true; 
      reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 
      reqFTP.Method = WebRequestMethods.Ftp.ListDirectory; 
      reqFTP.Proxy = null; 
      reqFTP.KeepAlive = false; 
      reqFTP.UsePassive = false; 
      response = reqFTP.GetResponse(); 
      reader = new StreamReader(response.GetResponseStream()); 
      string line = reader.ReadLine(); 
      while (line != null) 
      { 
       result.Append(line); 
       result.Append("\n"); 
       line = reader.ReadLine(); 
      } 
      // to remove the trailing '\n' 
      result.Remove(result.ToString().LastIndexOf('\n'), 1); 
      return result.ToString().Split('\n'); 
     } 
     catch (Exception ex) 
     { 
      if (reader != null) 
      { 
       reader.Close(); 
      } 
      if (response != null) 
      { 
       response.Close(); 
      }     
      downloadFiles = null; 
      return downloadFiles; 
     } 
    } 

    private void Download(string file) 
    {      
     try 
     {     
      string uri = "ftp://" + ftpServerIP + "/" + remoteDir + "/" + file; 
      Uri serverUri = new Uri(uri); 
      if (serverUri.Scheme != Uri.UriSchemeFtp) 
      { 
       return; 
      }  
      FtpWebRequest reqFTP;     
      reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + remoteDir + "/" + file));         
      reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);     
      reqFTP.KeepAlive = false;     
      reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;         
      reqFTP.UseBinary = true; 
      reqFTP.Proxy = null;     
      reqFTP.UsePassive = false; 
      FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 
      Stream responseStream = response.GetResponseStream(); 
      FileStream writeStream = new FileStream(localDestnDir + "\" + file, FileMode.Create);     
      int Length = 2048; 
      Byte[] buffer = new Byte[Length]; 
      int bytesRead = responseStream.Read(buffer, 0, Length);    
      while (bytesRead > 0) 
      { 
       writeStream.Write(buffer, 0, bytesRead); 
       bytesRead = responseStream.Read(buffer, 0, Length); 
      }     
      writeStream.Close(); 
      response.Close(); 
     } 
     catch (WebException wEx) 
     { 
      MessageBox.Show(wEx.Message, "Download Error"); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message, "Download Error"); 
     } 
    } 
相关问题