How to recursively delete FTP directory?

+2 votes
asked Jan 13, 2010 by Rebex KB (8,240 points)
edited Jul 4, 2012

I want to delete directory (including all files and subfolders in it) on the FTP server using Rebex FTP.

Applies to: Rebex FTP/SSL

3 Answers

+2 votes
answered Mar 13, 2012 by Lukas Matyska (47,950 points)
edited Jul 4, 2012
 
Best answer

In Release 2012 R1 the multi-file Delete() method was introduced. It can be used as follows:

Ftp client = new Ftp();
client.Connect(...);
client.Login(...);

client.Delete("remote_directory", Rebex.IO.TraversalMode.Recursive);
commented Jul 4, 2012 by Martin Vobr (12,900 points)
edited Jul 4, 2012

Same method for recursive delete is available in both Rebex FTP/SSL (http://www.rebex.net/ftp-ssl.net) and Rebex SFTP (http://www.rebex.net/sftp.net)

+2 votes
answered Jan 13, 2010 by Rebex KB (8,240 points)
edited May 24, 2011

Try the following code, but be careful – symlinks on Unix-like systems can make this quite problematic. You can encounter folder which is in fact symlink pointing to another directory outside original folder. In such case you may delete more than you wanted.

public static void DeleteDirectory(Ftp ftp, string remotePath)
{
    Console.WriteLine("Deleting directory: '{0}'",remotePath);

    // change the directory
    ftp.ChangeDirectory(remotePath);

    // delete all files from the remotePath directory
    FtpList files = ftp.GetList();
    for (int i = 0; i < files.Count; i++)
    {
        if (files[i].IsFile)
        {
            Console.WriteLine("Deleting file: '{0}'", files[i].Name);

            ftp.DeleteFile(files[i].Name);
        }
    }

    // delete all subdirectories in the remotePath directory
    for (int i = 0; i < files.Count; i++)
    {
        if (files[i].IsDirectory)
            DeleteDirectory(ftp, files[i].Name);
    }

    // delete this directory
    ftp.ChangeDirectory("..");
    ftp.RemoveDirectory(remotePath);
}
commented Dec 7, 2010 by Duncan (130 points)
edited May 24, 2011

Is there a VB.Net version of the above code available? I tried converting but I cannot get it to delete all folders and files.

0 votes
answered Dec 7, 2010 by Martin Vobr (12,900 points)
edited May 24, 2011

VB.NET version of previous answer

Public Sub DeleteDirectory(ByVal ftp As Ftp, ByVal remotePath As String)

Console.WriteLine("Deleting directory: '{0}'", remotePath)

''# change the directory
  ftp.ChangeDirectory(remotePath)

''# delete all files from the remotePath directory
  Dim files As FtpList = ftp.GetList()
  Dim i As Integer
  For i = 0 To files.Count - 1

If (files.Item(i).IsFile) Then
      Console.WriteLine("Deleting file: '{0}'", files.Item(i).Name)

ftp.DeleteFile(files.Item(i).Name)
    End If
  Next i

''# delete all subdirectories in the remotePath directory
  For i = 0 To files.Count - 1

If (files.Item(i).IsDirectory) Then
      DeleteDirectory(ftp, files.Item(i).Name)
    End If
  Next i

''# delete this directory
  ftp.ChangeDirectory("..")
  ftp.RemoveDirectory(remotePath)
End Sub

You can test it with following code:

Sub Main()
  Dim ftp As New Ftp()
  ftp.Connect("ftpsite")
  ftp.Login("username", "password")

Dim homeDir As String = "/incoming"
  ftp.ChangeDirectory(homeDir)

''# create a directory structure
  CreateDirIfNotExists(ftp, "a")
  CreateFilIfNotExists(ftp, "a/a.txt")
  CreateFilIfNotExists(ftp, "a/a2.txt")
  CreateDirIfNotExists(ftp, "a/aa")
  CreateDirIfNotExists(ftp, "a/b")
  CreateDirIfNotExists(ftp, "a/b/bb")
  CreateFilIfNotExists(ftp, "a/b/bb/file1.txt")
  CreateFilIfNotExists(ftp, "a/b/bb/file2.txt")
  CreateFilIfNotExists(ftp, "a/b/bb/file3.txt")
  CreateDirIfNotExists(ftp, "a/b/bb/bbb")
  CreateDirIfNotExists(ftp, "a/b/abc")

Console.WriteLine("------------")
  ''# delete recursive
  DeleteDirectory(ftp, "a")

ftp.Disconnect()

End Sub

Public Sub CreateFilIfNotExists(ByVal ftp As Ftp, ByVal remotepath As String)

If (Not ftp.FileExists(remotepath)) Then
    Dim ms As New MemoryStream()
    ms.WriteByte(32)
    ms.Seek(0, SeekOrigin.Begin)
    ftp.PutFile(ms, remotepath)
    Console.WriteLine("Created file " + remotepath)
  Else
    Console.WriteLine("File creation skipped. Already exists. " + remotepath)
  End If
End Sub

Public Sub CreateDirIfNotExists(ByVal ftp As Ftp, ByVal remotepath As String)
  If (Not ftp.DirectoryExists(remotepath)) Then
    Console.WriteLine("Creating directory " + remotepath)
    ftp.CreateDirectory(remotepath)
  Else
    Console.WriteLine("Directory creation skipped. Already exists. " + remotepath)
  End If
End Sub

EDIT: Fixed loop boundaries and added test code.

commented Dec 7, 2010 by Duncan 1 (100 points)
edited May 24, 2011

Thanks for your post Martin. The errors I got appear to be from the fact that where I was using Filezilla to set up the folders, Filezilla had locked the files, even though I was not viewing that directory so disconnecting Filezilla solved it.

The only amendment needed to your code is to ensure it is...

For i = 0 To files.Count -1, i.e. add the -1 at the end.

Many thanks Duncan

commented Dec 8, 2010 by Martin Vobr (12,900 points)
Thanks Duncan. I've edited my answer and fixed loop boundaries as suggested. I've also added test code.
...