2011-01-25 635 views
1

我想刪除FTP中的文件夾。FTPClient如何刪除目錄?

Can FTPClient object delete it?

+0

您登錄時所需要的用戶能夠擁有正確的權限 - 如果他們這樣做,然後他們可以刪除目錄,你會文件 - 如果你沒有,那麼你將有0權限 – stack72 2011-01-25 19:54:32

回答

2

FtpWebRequest提供刪除操作。 下面是一段代碼來實現這一目標:

   FtpWebRequest reqFTP = FtpWebRequest.Create(uri); 
       // Credentials and login handling... 

       reqFTP.Method = WebRequestMethods.Ftp.DeleteFile; 

       string result = string.Empty; 
       FtpWebResponse response = reqFTP.GetResponse(); 
       long size = response.ContentLength; 
       Stream datastream = response.GetResponseStream(); 
       StreamReader sr = new StreamReader(datastream); 
       result = sr.ReadToEnd(); 
       sr.Close(); 
       datastream.Close(); 
       response.Close(); 

應該對文件和目錄。的確,請檢查您是否擁有正確的權限。

此外,您不能刪除文件夾,而他們不是空的。您必須遞歸遍歷它們才能刪除內容。

由於拋到正確的權限問題並不總是很清楚的例外...

+4

當使用`WebRequestMethods.Ftp.DeleteFile`選項來嘗試刪除FTP服務器上的文件夾時,我得到'文件未找到'錯誤。當使用`WebRequestMethods.Ftp.RemoveDirectory`選項時,該目錄已成功刪除。 – Sheridan 2013-02-27 11:28:00

+1

即使空文件夾沒有刪除文件夾 – 2014-03-25 00:21:19

-2

着力點

如上所述..

你不能刪除文件夾,而他們是不是空的。您必須遞歸遍歷它們才能刪除內容。

+0

正如您所說的,已經在接受的答案中提到過。 – Dirk 2014-02-13 13:26:33

4

我找到工作的唯一方法是依靠「WebRequestMethods.Ftp.DeleteFile」,它會給一個異常櫃面與文件的文件夾或文件夾,所以我創建了一個新interenal方法deletedirectory遞歸 這裏是代碼

public void delete(string deleteFile) 
      { 
       try 
       { 
        /* Create an FTP Request */ 
        ftpRequest = (FtpWebRequest)WebRequest.Create(host + "/" + deleteFile); 
        /* Log in to the FTP Server with the User Name and Password Provided */ 
        ftpRequest.Credentials = new NetworkCredential(user, pass); 
        /* When in doubt, use these options */ 
        ftpRequest.UseBinary = true; 
        ftpRequest.UsePassive = true; 
        ftpRequest.KeepAlive = true; 
        /* Specify the Type of FTP Request */ 
        ftpRequest.Method = WebRequestMethods.Ftp.DeleteFile; 
        /* Establish Return Communication with the FTP Server */ 
        ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); 
        /* Resource Cleanup */ 
        ftpResponse.Close(); 
        ftpRequest = null; 
       } 
       catch (Exception ex) { 
        //Console.WriteLine(ex.ToString()); 
        try 
        { 
         deleteDirectory(deleteFile); 
        } 
        catch { } 


       } 
       return; 
      } 

和目錄刪除

/* Delete Directory*/ 
      private void deleteDirectory(string directoryName) 
      { 
       try 
       { 
        //Check files inside 
        var direcotryChildren = directoryListSimple(directoryName); 
        if (direcotryChildren.Any() && (!string.IsNullOrWhiteSpace(direcotryChildren[0]))) 
        { 
         foreach (var child in direcotryChildren) 
         { 
          delete(directoryName + "/" + child); 
         } 
        } 


        /* Create an FTP Request */ 
        ftpRequest = (FtpWebRequest)WebRequest.Create(host + "/" + directoryName); 
        /* Log in to the FTP Server with the User Name and Password Provided */ 
        ftpRequest.Credentials = new NetworkCredential(user, pass); 
        /* When in doubt, use these options */ 
        ftpRequest.UseBinary = true; 
        ftpRequest.UsePassive = true; 
        ftpRequest.KeepAlive = true; 
        /* Specify the Type of FTP Request */ 
        ftpRequest.Method = WebRequestMethods.Ftp.RemoveDirectory; 

        /* Establish Return Communication with the FTP Server */ 
        ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); 
        /* Resource Cleanup */ 
        ftpResponse.Close(); 
        ftpRequest = null; 
       } 
       catch (Exception ex) { Console.WriteLine(ex.ToString()); } 
       return; 
      } 

列表Direcotry孩子

/* List Directory Contents File/Folder Name Only */ 
      public string[] directoryListSimple(string directory) 
      { 
       try 
       { 
        /* Create an FTP Request */ 
        ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + directory); 
        /* Log in to the FTP Server with the User Name and Password Provided */ 
        ftpRequest.Credentials = new NetworkCredential(user, pass); 
        /* When in doubt, use these options */ 
        ftpRequest.UseBinary = true; 
        ftpRequest.UsePassive = true; 
        ftpRequest.KeepAlive = true; 
        /* Specify the Type of FTP Request */ 
        ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory; 
        /* Establish Return Communication with the FTP Server */ 
        ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); 
        /* Establish Return Communication with the FTP Server */ 
        ftpStream = ftpResponse.GetResponseStream(); 
        /* Get the FTP Server's Response Stream */ 
        StreamReader ftpReader = new StreamReader(ftpStream); 
        /* Store the Raw Response */ 
        string directoryRaw = null; 
        /* Read Each Line of the Response and Append a Pipe to Each Line for Easy Parsing */ 
        try { while (ftpReader.Peek() != -1) { directoryRaw += ftpReader.ReadLine() + "|"; } } 
        catch (Exception ex) { Console.WriteLine(ex.ToString()); } 
        /* Resource Cleanup */ 
        ftpReader.Close(); 
        ftpStream.Close(); 
        ftpResponse.Close(); 
        ftpRequest = null; 
        /* Return the Directory Listing as a string Array by Parsing 'directoryRaw' with the Delimiter you Append (I use | in This Example) */ 
        try { string[] directoryList = directoryRaw.Split("|".ToCharArray()); return directoryList; } 
        catch (Exception ex) { Console.WriteLine(ex.ToString()); } 
       } 
       catch (Exception ex) { Console.WriteLine(ex.ToString()); } 
       /* Return an Empty string Array if an Exception Occurs */ 
       return new string[] { "" }; 
      } 

      /* List Directory Contents in Detail (Name, Size, Created, etc.) */ 
      public string[] directoryListDetailed(string directory) 
      { 
       try 
       { 
        /* Create an FTP Request */ 
        ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + directory); 
        /* Log in to the FTP Server with the User Name and Password Provided */ 
        ftpRequest.Credentials = new NetworkCredential(user, pass); 
        /* When in doubt, use these options */ 
        ftpRequest.UseBinary = true; 
        ftpRequest.UsePassive = true; 
        ftpRequest.KeepAlive = true; 
        /* Specify the Type of FTP Request */ 
        ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails; 
        /* Establish Return Communication with the FTP Server */ 
        ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); 
        /* Establish Return Communication with the FTP Server */ 
        ftpStream = ftpResponse.GetResponseStream(); 
        /* Get the FTP Server's Response Stream */ 
        StreamReader ftpReader = new StreamReader(ftpStream); 
        /* Store the Raw Response */ 
        string directoryRaw = null; 
        /* Read Each Line of the Response and Append a Pipe to Each Line for Easy Parsing */ 
        try { while (ftpReader.Peek() != -1) { directoryRaw += ftpReader.ReadLine() + "|"; } } 
        catch (Exception ex) { Console.WriteLine(ex.ToString()); } 
        /* Resource Cleanup */ 
        ftpReader.Close(); 
        ftpStream.Close(); 
        ftpResponse.Close(); 
        ftpRequest = null; 
        /* Return the Directory Listing as a string Array by Parsing 'directoryRaw' with the Delimiter you Append (I use | in This Example) */ 
        try { string[] directoryList = directoryRaw.Split("|".ToCharArray()); return directoryList; } 
        catch (Exception ex) { Console.WriteLine(ex.ToString()); } 
       } 
       catch (Exception ex) { Console.WriteLine(ex.ToString()); } 
       /* Return an Empty string Array if an Exception Occurs */ 
       return new string[] { "" }; 
      } 
+0

`UseBinary`和`UsePassive`對`RemoveDirectory`和`DeleteFile`沒有任何影響,所以在設置它時會令人困惑。無論如何,它們都默認爲`true`(對於`KeepAlive`也是一樣的)。 – 2016-09-09 13:17:43

-2
public void Deletedir(string remoteFolder) 
{ 
    try 
    { 
     /* Create an FTP Request */ 
     ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/"+ remoteFolder); 
     /* Log in to the FTP Server with the User Name and Password Provided */ 
     ftpRequest.Credentials = new NetworkCredential(user, pass); 
     /* When in doubt, use these options */ 
     ftpRequest.UseBinary = true;***strong text*** 
     ftpRequest.UsePassive = true; 
     ftpRequest.KeepAlive = true; 
     /* Specify the Type of FTP Request */ 
     ftpRequest.Method = WebRequestMethods.Ftp.RemoveDirectory; 
     /* Establish Return Communication with the FTP Server */ 
     ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); 
     /* Get the FTP Server's Response Stream */ 
     ftpStream = ftpResponse.GetResponseStream(); 
     /* Open a File Stream to Write the Downloaded File */ 
    } 
    catch { } 
} 

這就是你可以使用的代碼。 這裏是你如何使用它,例如,點擊按鈕。

private void button5_Click(object sender, EventArgs e) 
{ 
    ftp ftpClient = new ftp(@"SERVICE PROVIDER", "USERNAME", "PASSWORD"); 
    ftpClient.Deletedir("DIRECTORY U WANT TO DELETE"); 
} 

只要記住您的文件夾應該是空的。

5

要刪除空目錄,使用FtpWebRequestRemoveDirectory 「方法」:

void DeleteFtpDirectory(string url, NetworkCredential credentials) 
{ 
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url); 
    request.Method = WebRequestMethods.Ftp.RemoveDirectory; 
    request.Credentials = credentials; 
    request.GetResponse().Close(); 
} 

這樣使用它:

string url = "ftp://ftp.example.com/directory/todelete"; 
NetworkCredential credentials = new NetworkCredential("username", "password"); 
DeleteFtpDirectory(url, credentials); 

雖然它獲得的方式更加複雜,如果你需要刪除一個非空的目錄。 FtpWebRequest類(或.NET框架中的任何其他FTP實現)不支持遞歸操作。你必須執行遞歸自己:

  • 列出遠程目錄
  • 迭代的條目,刪除文件,並在遞歸到子目錄(再次列出這些,等)

棘手的部分是從子目錄中識別文件。 FtpWebRequest無法通過便攜式方式執行此操作。 FtpWebRequest不幸地不支持MLSD命令,這是在FTP協議中使用文件屬性檢索目錄列表的唯一便攜方式。另請參閱Checking if object on FTP server is file or directory

的選項有:

  • 上那是一定要失敗的文件,併成功爲目錄(反之亦然)的文件名再做一次手術。即你可以嘗試下載「名稱」。如果成功,它就是一個文件,如果失敗了,它就是一個目錄。但是,如果您有大量條目,這可能會成爲性能問題。
  • 你可能是幸運的,在特定情況下,可以通過文件名告訴從目錄中的文件(即所有文件的擴展名,而子目錄不)
  • 您使用長的目錄列表(LIST命令= ListDirectoryDetails方法)並嘗試解析服務器特定的列表。許多FTP服務器使用* nix風格的列表,其中您在入口最開始處用d標識目錄。但是許多服務器使用不同的格式。以下示例使用此方法(假定爲* nix格式)。
  • 在這種特定情況下,您可以嘗試將條目作爲文件刪除。如果刪除失敗,請嘗試將該條目列爲目錄。如果列表成功,您會認爲它是一個文件夾並據此進行操作。不幸的是,當您嘗試列出文件時,某些服務器不會出錯。他們只會爲文件返回一個包含單個條目的列表。
static void DeleteFtpDirectory(string url, NetworkCredential credentials) 
{ 
    FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(url); 
    listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails; 
    listRequest.Credentials = credentials; 

    List<string> lines = new List<string>(); 

    using (FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse()) 
    using (Stream listStream = listResponse.GetResponseStream()) 
    using (StreamReader listReader = new StreamReader(listStream)) 
    { 
     while (!listReader.EndOfStream) 
     { 
      lines.Add(listReader.ReadLine()); 
     } 
    } 

    foreach (string line in lines) 
    { 
     string[] tokens = 
      line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries); 
     string name = tokens[8]; 
     string permissions = tokens[0]; 

     string fileUrl = url + name; 

     if (permissions[0] == 'd') 
     { 
      DeleteFtpDirectory(fileUrl + "/", credentials); 
     } 
     else 
     { 
      FtpWebRequest deleteRequest = (FtpWebRequest)WebRequest.Create(fileUrl); 
      deleteRequest.Method = WebRequestMethods.Ftp.DeleteFile; 
      deleteRequest.Credentials = credentials; 

      deleteRequest.GetResponse(); 
     } 
    } 

    FtpWebRequest removeRequest = (FtpWebRequest)WebRequest.Create(url); 
    removeRequest.Method = WebRequestMethods.Ftp.RemoveDirectory; 
    removeRequest.Credentials = credentials; 

    removeRequest.GetResponse(); 
} 

使用它的方式與以前的(平面)實現相同。


或者使用支持遞歸操作的第三方庫。

例如與WinSCP .NET assembly就可以刪除與單個調用整個目錄到Session.RemoveFiles

// Setup session options 
SessionOptions sessionOptions = new SessionOptions 
{ 
    Protocol = Protocol.Ftp, 
    HostName = "example.com", 
    UserName = "user", 
    Password = "mypassword", 
}; 

using (Session session = new Session()) 
{ 
    // Connect 
    session.Open(sessionOptions); 

    // Delete folder 
    session.RemoveFiles("/directory/todelete").Check(); 
} 

內部,WinSCP賦予使用MLSD命令,如果服務器支持。如果不是,則使用LIST命令並支持數十種不同的列表格式。

(我的WinSCP的作者)