Monday, 1 June 2009

Comparing folder contents using dictionaries

Coming from a web programming background I properly cut my commercial programming teeth using PHP, although this was after a dabble with Fortran when studying engineering, and then later Turbo Pascal when studying geology.

I haven't touched PHP for a while, but there's two things I really miss - not having to declare variables (some call me agile, others lazy), and the simple associative arrays. They don't exist in VB.NET, but the dictionary is a pretty cool alternative. Like an associative array a dictionary allows you to add any object as an item with a string as a key to access it, and edit members later if you wish.

A common use, especially amongst BIM & CAD programmers, would be for handling file information, as I had to do today. The following code takes a 'master' and 'client' directory path, looks at all the files in them both and stores their names and modified dates as key/value pairs in dictionaries. Then we compare the dictionaries using SequenceEqual, and if there's a difference we loop through the master's keys looking for the keys and values in the client dictionary. Any files that are missing or different are returned in a collection, for action elsewhere.

Private Function compareTwoFolders(ByVal masterDir As String, ByVal clientDir As String)

Dim filesNeedingUdating As New Collection(Of String)
Dim currentFileInfo As FileInfo

'get all master files
Dim masterFileCollection As ReadOnlyCollection(Of String) = _
My.Computer.FileSystem.GetFiles(masterDir, FileIO.SearchOption.SearchAllSubDirectories)

'get all client files
Dim clientFilesCollection As ReadOnlyCollection(Of String) = _
My.Computer.FileSystem.GetFiles(clientDir, FileIO.SearchOption.SearchAllSubDirectories)

'create dictionary of master file names and mod dates
Dim masterFiles As New Dictionary(Of String, String)

Dim i As Integer = 0
Do While (i < masterFileCollection.Count)
currentFileInfo = My.Computer.FileSystem.GetFileInfo(masterFileCollection(i))
masterFiles.Add(fixFilePath(masterFileCollection(i)), currentFileInfo.LastWriteTimeUtc)
i = i + 1

'create dictionary of client file names and mod dates
Dim clientFiles As New Dictionary(Of String, String)

Dim z As Integer = 0
Do While (z < clientFilesCollection.Count)
currentFileInfo = My.Computer.FileSystem.GetFileInfo(clientFilesCollection(z))
clientFiles.Add(fixFilePath(clientFilesCollection(z)), currentFileInfo.LastWriteTimeUtc)
z = z + 1

'check if dictionaries are equal
If Not masterFiles.SequenceEqual(clientFiles) Then
'there are differences in the sequences, so lets investigate
'loop through master dictionary finding what's different
For Each masterKey As String In masterFiles.Keys
If clientFiles.ContainsKey(masterKey) Then
If Not clientFiles(masterKey) = masterFiles(masterKey) Then
'different mod dates, add file to collection
End If
'no file found, add file to collection
End If


End If

Return filesNeedingUdating

End Function

fixFilePath, which I haven't included, is just a function that reduces the full file path (C:\\ etc) to the directory that your interested in, so that they can properly be compared. If you're comparing between two machines with the identical file structures you won't need this.

No comments:

Post a Comment

Comments are moderated, so you'll have to wait a little bit before they appear!