FTPClient如何删除目录?

我想删除FTP中的文件夹。

可以将FTPClient对象删除吗?

FtpWebRequest提供Delete操作。 这是一段代码来实现:

  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(); 

它应该适用于文件和目录。 确实,请检查您是否拥有正确的权限。

此外,如果文件夹不为空,则无法删除它们。 您必须递归遍历它们才能删除内容。

由于权限问题引发的exception并不总是很清楚……

要删除空目录,请使用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协议中检索具有文件属性的目录列表的唯一可移植方式。 另请参阅检查FTP服务器上的对象是文件还是目录 。

你的选择是:

  • 对文件名执行操作,该文件名肯定会对文件失败并对目录成功(反之亦然)。 即你可以尝试下载“名称”。 如果成功,它是一个文件,如果失败,它就是一个目录。 但是当您有大量条目时,这可能会成为性能问题。
  • 您可能很幸运,在您的特定情况下,您可以通过文件名告诉目录中的文件(即所有文件都有扩展名,而子目录没有)
  • 您使用长目录列表( 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 lines = new List(); 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程序集 ,只需调用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的作者)

我发现工作的唯一方法是依赖“WebRequestMethods.Ftp.DeleteFile”并且它会给文件夹或文件夹带有文件的exception,所以我在这里创建了一个新的interenal方法,以递归方式删除目录。

 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[] { "" }; } 

很重要的一点

正如刚才提到的..

当文件夹不为空时,您无法删除它们。 您必须递归遍历它们才能删除内容。

 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"); } 

请记住,您的文件夹应该是EMPTY。