|
|
Title | Get a sorted list of the files in a directory |
Keywords | sorting, directory, files, quicksort, Dir |
Categories | Files and Directories, Algorithms |
|
|
The SortedFiles function returns a sorted list of files in a directory. The function uses Dir$ to list the files in the directory.
If the exclude_self parameter is True, the function skips the file "." that indicates the current directory.
If the exclude_parent parameter is True, the function skips the file ".." that indicates the parent directory.
After it has saved the file names in an array, the function calls subroutine Quicksort to sort the array.
|
|
' Return an array containing the names of the
' files in the directory sorted alphabetically.
Private Function SortedFiles(ByVal dir_path As String, _
Optional ByVal exclude_self As Boolean = True, _
Optional ByVal exclude_parent As Boolean = True) As _
String()
Dim num_files As Integer
Dim files() As String
Dim file_name As String
file_name = Dir$(dir_path)
Do While Len(file_name) > 0
' See if we should skip this file.
If Not _
(exclude_self And file_name = ".") Or _
(exclude_parent And file_name = "..") _
Then
' Save the file.
num_files = num_files + 1
ReDim Preserve files(1 To num_files)
files(num_files) = file_name
End If
' Get the next file.
file_name = Dir$()
Loop
' Sort the list of files.
Quicksort files, 1, num_files
' Return the list.
SortedFiles = files
End Function
|
|
The Quicksort subroutine sorts the items in an array. The idea is to:
- Pick a random dividing item from the array.
- Move items greater than the dividing item to the end of the array and move other items to the beginning of the array.
- Recursively call Quicksort to sort the two halves of the array.
For more information on quicksort, other sorting algorithms, and lots of other algorithms and data structures,
see Ready-to-Run Visual Basic Algorithms.
|
|
' Use Quicksort to sort a list of strings.
Private Sub Quicksort(list() As String, _
ByVal min As Long, ByVal max As Long)
Dim mid_value As String
Dim hi As Long
Dim lo As Long
Dim i As Long
' If there is 0 or 1 item in the list,
' this sublist is sorted.
If min >= max Then Exit Sub
' Pick a dividing value.
i = Int((max - min + 1) * Rnd + min)
mid_value = list(i)
' Swap the dividing value to the front.
list(i) = list(min)
lo = min
hi = max
Do
' Look down from hi for a value < mid_value.
Do While list(hi) >= mid_value
hi = hi - 1
If hi <= lo Then Exit Do
Loop
If hi <= lo Then
list(lo) = mid_value
Exit Do
End If
' Swap the lo and hi values.
list(lo) = list(hi)
' Look up from lo for a value >= mid_value.
lo = lo + 1
Do While list(lo) < mid_value
lo = lo + 1
If lo >= hi Then Exit Do
Loop
If lo >= hi Then
lo = hi
list(hi) = mid_value
Exit Do
End If
' Swap the lo and hi values.
list(hi) = list(lo)
Loop
' Sort the two sublists.
Quicksort list, min, lo - 1
Quicksort list, lo + 1, max
End Sub
|
|
Willy Vanhaelen has this excellent suggestion:
I thought instead of first making the list and then sort it, I better
could do the sorting while making the list (perhaps I reinvented the
wheel?).
So I simply replaced:
|
|
' Save the file.
num_files = num_files + 1
ReDim Preserve files(1 To num_files)
files(num_files) = file_name
|
|
with:
|
|
' Save the file.
num_files = num_files + 1
ReDim Preserve files(1 To num_files)
'look to see where in the list it belongs
For i = num_files To 2 Step -1
If file_name >= files(i - 1) Then Exit For
files(i) = files(i - 1)
Next i
files(i) = file_name
|
|
For long lists quick sort is faster but for small lists and especially
when they are already mostly in sorted order, it doesn't make any
difference but my solution then has the benefit of being extremely
simple (only 4 lines of code!).
Willy is absolutely correct. One of the most important rules I preach in my book
Bug Proofing Visual Basic is that you should keep things simple
until you have proven the simple approach won't work.
Make it work correctly first, then make it work faster if necessary.
Willy's solution is much simpler and therefore a better first solution. Considering that most
directories contain no more than a few hundred files, this solution will probably be fast enough
fine for most applications and it will be easier to debug and maintain.
The only time you should use a more complex technique than necessary is if you already have a routine
debugged and running correctly. I did have the quicksort routine lying around so I would probably
use it in a real application, but Willy's method (or an even simpler solution using a Collection)
would be better for this example.
|
|
|
|
|
|