2011-01-25 111 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的作者)