Page 1 of 1

Using recursion to create a program to backup folders Rate Topic: -----

#1 Cal-cium  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 13
  • View blog
  • Posts: 26
  • Joined: 27-January 15

Posted 20 July 2016 - 07:45 AM

There are a lot of arguments for and against recursion. But I will not dwell long on whether it is good or bad, this website tho can explain in more detail. This tutorial will show how Recursion can be used to create a program that can backup your folders, also giving the option to the user whether or not to copy existing files even if they are newer than the existing ones (useful if you only want to copy files if they are not there already).

For those that do not know what Recursion is, a recursive method is a method that calls upon itself.

Quote

In order to understand recursion, one must first understand recursion


In order to create your backup program, you will need on your windows form application:
  • 2 TextBoxes - 1 called txtMainFolder and 1 called txtFolderBackup
  • 1 Button - Name this btnBackup
  • 1 Checkbox - Name this cbNoOverwrite


Spoiler for whole code:
Spoiler


First thing you need to is declare global variables that will be used and turn Option strict on:
Option Strict On
Imports System.IO


Dim FolderDirectory As New Hashtable 
Dim MainFolder As String
Dim lstAllFiles As New List(Of String)
Dim lstDirectories As New List(Of String)
Dim CountMarker As Integer = 0


These should be self explanatory once you see the whole code. Next we will add the code for when the user has entered in the folder locations. txtMainFolder should be the folder location from where the program will copy all files and folders from and txtFolderBackup will be the location it will copy to. The program will copy the files and folders in the same layout as where it copied it from.

Private Sub btnBackup_Click(sender As Object, e As EventArgs) Handles btnBackup.Click

        'Check textboxes aren't empty
        If txtFolderBackup.Text = "" OrElse txtMainFolder.Text = "" Then
            MessageBox.Show("Please fill in all boxes!", "User Error ")
        Else
            MainFolder = txtMainFolder.Text
            Dim count As Integer = 0
            FolderDirectory.Add(count, txtFolderBackup.Text)

            lstAllFiles.AddRange(Directory.GetFiles(MainFolder))

            'copy files that are in the primary folder
            CopyFiles(count)

            'Add directories
            lstDirectories.AddRange(Directory.GetDirectories(MainFolder))

            'start the loop to search through all the folders and back up them
            'foldermarker is used to keep track of folder locations, especially useful as this uses recursion, as the foldermarker keeps track of folder layout
            Dim FolderMarker As Integer = 0
            For Each folder In lstDirectories
                CopyDirectories(folder, count, FolderMarker)
            Next

            'Clear all lists and count, so program is ok to run again
            lstAllFiles.Clear()
            lstDirectories.Clear()
            FolderDirectory.Clear()
            count = 0
            CountMarker = 0
            txtFolderBackup.Text = ""
            txtMainFolder.Text = ""
            cbNoOverwrite.Checked = False

            MessageBox.Show("All files are backed up!", "Completed")

        End If

    End Sub


Once this button has been clicked, it will first assign variables to its corresponding lists and check to make sure all text boxes are filled in. The program will first copy the files that are in the main folder by calling the sub procedure CopyFiles. The program will then read in all the directories in the folder and start reading sub procedure CopyDirectories, which is the sub taht will use recursion to call upon itself. After its done this it will clear all lists files etc and show a message that it's completed.

The sub procedure CopyFiles:
    ''' <summary>
    ''' This is a method that copies files in the chosen directory into the backup location
    ''' </summary>
    ''' <param name="count">This parameter is used to pick the correct folder directory when copying files over</param>
    ''' <remarks></remarks>
    Sub CopyFiles(ByVal count As Integer)
        Try
            'For each file in folder grab information about that file.
            For Each File In lstAllFiles
                Dim FileInfo As New FileInfo(File)
                Dim Filename As String = FileInfo.Name
                Dim FileLocation As String = FileInfo.FullName
                Dim FileDate As Date = FileInfo.LastWriteTime

                'If the backup folder contains the file already, compare dates on file and if newer overwrite
                If System.IO.File.Exists(Path.Combine(CStr(FolderDirectory(count)), Filename)) Then
                    Dim TempFileinfo As New FileInfo(Path.Combine(CStr(FolderDirectory(count)), Filename))
                    Dim TempFileDate As Date = TempFileinfo.LastWriteTime
                    Dim result As Integer = DateTime.Compare(FileDate, TempFileDate)
                    'if result is less than 0 then the file is earlier than the backed up file, if result equals 0 then they are the same, 
                    'if result is more than 0 then the file newer than the backuped file, so file needs to be copied over if newer
                    'Only overwrite file over if checkbox is not ticked, this way only files that are not previously there will get copied across
                    If result > 0 AndAlso cbNoOverwrite.Checked = False Then
                        System.IO.File.Copy(FileLocation, Path.Combine(CStr(FolderDirectory(count)), Filename), True)
                    End If
                Else
                    'file does not already exist so copy over
                    System.IO.File.Copy(FileLocation, Path.Combine(CStr(FolderDirectory(count)), Filename))
                End If
            Next
        Catch ex As Exception
            MessageBox.Show("Something went wrong. " & ex.ToString, "Data error ")
        End Try
    End Sub


This sub procedure is called upon every time the program reaches a new folder and will copy all files in that folder over to the new one. If the check box cbNoOverwrite is ticked then it will not overwrite the existing files.

The sub procedure CopyDirectories:
    ''' <summary>
    ''' This sub copies folder directories over to the backup location and uses recursion to call itself so that it looks at directories in itself and also calls CopyFiles to copy the files over in those directories
    ''' </summary>
    ''' <param name="Folder">This parameter holds the folder location</param>
    ''' <param name="count">This parameter holds the count used to add more directories into the hashtable and used so that it creates a unique ID for each folder</param>
    ''' <param name="FolderMarker">this parameter is used a marker so that it adds the correct folder directory path</param>
    ''' <remarks></remarks>
    Sub CopyDirectories(ByVal Folder As String, ByVal count As Integer, ByVal FolderMarker As Integer)
        Try
            'Check if folder exists in backup and if it doesnt copy entire folder over
            'if folder exists then go through each folder and copy files/folders over
            'use recursion to call 
            Dim FolderInfo As New DirectoryInfo(Folder)
            Dim Folderlocation As String = FolderInfo.FullName
            Dim FolderName As String = FolderInfo.Name
            Dim lstTempFolderDirectories As New List(Of String)
            lstTempFolderDirectories.AddRange(Directory.GetDirectories(Folderlocation))

            'if the folder does not exist then copy folder and contents over otherwise read through contents and update if necassary
            If Directory.Exists(Path.Combine(CStr(FolderDirectory(count)), FolderName)) Then
                lstAllFiles.Clear()
                lstAllFiles.AddRange(Directory.GetFiles(Folderlocation))

                'Loop until the count is higher than the countmarker so that the count is a new number and that the FolderDirectory doesnt try to add a directory in a used key
                Do Until count > CountMarker
                    count += 1
                Loop
                CountMarker = count

                'Add directory to hashtable
                FolderDirectory.Add((count), (Path.Combine(CStr(FolderDirectory(FolderMarker)), FolderName)))

                'Add 1 to the foldermarker here
                FolderMarker += 1

                'Copy files in this directory over
                CopyFiles(count)

                If lstTempFolderDirectories.Contains(Nothing) Then
                Else
                    'Use recursion to call this same subroutine so that it can go through each subfolders
                    For Each Folder In lstTempFolderDirectories
                        CopyDirectories(Folder, count, FolderMarker)
                    Next
                End If
            Else
                'if folder does not exist then copy over whole of the directory including everything inside it
                My.Computer.FileSystem.CopyDirectory(Folderlocation, Path.Combine(CStr(FolderDirectory(FolderMarker)), FolderName))
            End If

        Catch ex As Exception
            MessageBox.Show("Something went wrong. " & ex.ToString, "Data error ")
        End Try
    End Sub


The sub procedure CopyDirectories uses recursion to call upon itself to read through each folder and copy them and call upon CopyFiles to copy the files over. Recursion is extremely helpful in this case because when backing folders up, each folder it gets to can have more folders inside them to back up and so on. So once it does finished with one folder it will go back and can continue with next folder and read through that folder. It does this by the use of a Hash Table and giving each directory a unique number by use of the FolderMarker. Tho if the folder doesnt exist in the backip location then it will simply copy the folder over and all its contents.

I have commented throughout my code on what it does. So hopefully this has helped people. There are more ways of improving on this, for example adding a message box to ask the user do they want to overwrite an existing file rather than just having a check box.

Is This A Good Question/Topic? 0
  • +

Page 1 of 1