The FileSystemObject provides a modern, convenient, object-oriented, and coherent way to access the file system from many of the scripting environments used with the AWR Design Environment. While many environments including the built-in basic provide means for opening, reading and writing files the file system object provided by the Microsoft Scripting Library, the library that also contains the dictionary object, provides a more comprehensive solution to file manipulation.

The FileSystemObject

The FileSystemObject provides a objects arranged in a hierarchy consistent with the elements of the file system. The objects of this hierarchy are shown below in Figure 1.

Figure 1: FileSystemObject Object Hierarchy

Adding a Reference to the Microsoft Scripting Library

To use the FileSystemObject you will first need to add a reference to the Microsoft Scripting Library. In the AWR scripting environment select the References toolbar button. And then in the dialog find the Microsoft Scripting Runtime item and place a check next to the entry as shown in Figure 2.

Figure 2 Adding a reference to the Microsoft Scripting Runtime.

The FileSystemObject root object

At the root of the hierarchy is the FileSystemObject object itself. It exposes many methods and only one property, Drives, which returns a collection of all the drives in the system. The FileSystemObject object (abbreviated as FSO in the following text and code) is the only creatable object in the hierarchy - that is, it's the only that can be declared using the New keyword. All the other objects are dependent objects that derived from this one and are exposed in the form of properties or methods. See how easy it is to fill an array with the list of all the ready drives in their capacities:

 Sub Main
        Dim fso As Scripting.FileSystemObject
        Dim dr As Scripting.Drive

        Set fso = New Scripting.FileSystemObject

        ' Needed for not ready drives.
        On Error Resume Next

        Debug.Clear
        For Each dr In fso.Drives
                Debug.Print dr.DriveLetter & " [ " & dr.TotalSize & " ] "
        Next dr
End Sub

 

Table 1 below summaries the many methods exposed by the FileSystemObject. A few of them are also available (often with different names and syntax) as methods of the secondary Folder and File objects. Most of these methods add functionality to commands already present in the in the built Basic. For example, you can delete non-empty folders (be very careful!) and copy and rename multiple files and directories with a single command. You can easily extract portions of a filename without having to write special routines.

SyntaxDescription
BuildPath (Path,Name)Returns a complete filename, obtained by concatenating the path (relative or absolute) and name.
CopyFile (Source,Destination,[Overwrite])Copies one or more files: Source can include wildcards, and Destination is considered be a directory if it ends with a backslash. It overwrites files unless you set Overwrite to false.
CopyFolder (Source,Destination,[Overwrite])Same as CopyFile, but copies entire folder with their contents (sub-folders and files). If Destination doesn't correspond to an existing directory, it's created (but not of Source contains wildcards.
CreateFolder (Path) As FolderCreates a new Folder object and returns it; raises an error if the folder already exists
CreateTextFile (FileName,[Overwrite],[Unicode]) As TextStreamCreates a new TextFile object and returns it; set Overwrite = False to avoid overwriting existing file; setUnicode = True to create a Unicode TextFile object.
DeleteFile (FileSpec,[Force])Deletes one or more files. FileSpec can include wildcards; Set Force = True to force deletion of read-only files
DeleteFolder (FolderSpec,[Force])Deletes one or more Folders, together with their contents; set Force = True to force delete of read-only files
DriveExists (DriveName)Returns True if a given logical drive exits
FileExits (FileName)Returns True if a given file exists (The path can be relative to to the current directory.)
FolderExists (FolderName)Returns True if the given folder exists (The path can be relative to the current directory.)
GetAbsolutePathName (Path)Converts a path relative to the current directory into an absolute path.
GetBaseName (FileName)Extract the base filename (without its path and extension); it doesn't check whether the file and/or the path actually exists.
GetDrive (DriveName) As DriveReturns the Drive object that corresponds to the letter or the UNC path passed as an argument. (It checks that the drive actually exists).
GetDriveName (Path)Extracts the Drive from the path.
GetExtensionName (Path)Extracts the extension string from a filename.
GetFile (FileName)Returns the File object corresponding to the name passed as the argument. (Can be absolute or relative to the current directory)
GetFileName (Path)Extract the filename (without its path but with its extension); it doesn't check whether the file and/or path actually exists.
GetFolder (FolderName) As FolderReturns the Folder object corresponding to the path passed as the argument (Can be absolute or relative to the current directory)
GetParentFolderName (Path)Returns the name of the parent directory of the directory passed as teh argument (or an empty string if the parent directory doesn't exist.)
GetSpecialFolder (SpecialFolder) As FolderReturns a folder object that corresponds to one of the special Windows directories. SpecialFolder can be 0-WindowsFolder, 1-SystemFolder, 2-TemporaryFolder.
GetTempName() Returns the name of a non-existent file that can be used as a temporary file
MoveFile (Source,Destination)Same as CopyFile , but it deletes the source file. It can also move among different drives, if this function is supported by the operating system
MoveFolder (Source,Destination)Same as MoveFile but works on directories instead.
OpenTextFile (FileName,[IOMode],[Create],[Format]) As TextStreamOpens a text file and returns the corresponding TextStream object. IOMode can be one or a combination (use the OR operator) of the following constants: 1-ForReading, 2-ForWriting, 8-ForAppending; set Create to True if you want ot create a new file; Format can be 0-TristateFalse (ANSI), 1-TristateTrue (Unicode) or 2-TristateUseDefault (determined by the operating system).

Table 1: All the methods of the FileSystemObject object.

The Drive Object

The Drive object exposes only properties (no methods), all of which are summarized in Table 2. All the properties are read-only, except theVolumeName property. The following short code snippet determines the local drives that are ready and have at least 100MB of free space on them.

 Sub Main
        Dim fso As Scripting.FileSystemObject
        Dim dr As Scripting.Drive

        ' Get a FileSystemObject instance
        Set fso = New Scripting.FileSystemObject

        Debug.Clear
        For Each dr In fso.Drives
                If dr.IsReady Then
                        If dr.DriveType = Fixed Or dr.DriveType = Removeable Then
                                If dr.FreeSpace > 100 * 2 ^ 20 Then
                                        Debug.Print dr.Path & " [ " & dr.VolumeName & " ] = " & dr.FreeSpace
                                End If
                        End If
                End If
        Next dr
End Sub

 

Table 2 summaries the properties exposed by the Drive object.

SyntaxDescription
AvailableSpace The free space on the drive, in bytes; it usually coincides with the value returned by the FreeSpace property, unless the operating system supports disk quotes
DriveLetter The letter associated with the drive or an empty string for network drives not associated with a letter
DriveType A constant that indicates the type of the drive: 0-Unknown, 1-Removable, 2-Fixed, 3-Remote, 4-CDROM,5-RamDisk
FileSystem A string that describes the file system in use: FAT, NTFS, CDFS
FreeSpace The free space on the drive (See AvialableSpace)
IsReady True if the drive is ready, False otherwise
Path The path associated with the drive, without the backslash (for example C:)
RootFolder The folder that corresponds to the root directory
SerialNumber A long number that corresponds to the serial disk number.
ShareName The network shared name for the drive or an empty string if it isn't a network drive.
TotalSize The total capacity of the drive, in bytes
VolumeName The disk label (can be read and written)

Table 2: All the properties of the Drive object.

The Folder Object

The folder object represents an individual subdirectory. You can obtain a reference to such an object in different ways: by using the GetFolder orGetSpecialFolder methods of the root FileSystemObject object, through the RootFolder property of a Drive object, through the ParentFolder of the File object or another Folder object, or by iterating over the SubFolders collection of another Folder object. The folder object exposes a number of interesting properties, summarized in Table 3, but only the Attribute and Name properties can be written to. The most intriguing properties are probably the SubFolders and Files collections, which let you iterate through the subdirectories and files using an elegant and concise syntax, here is a short program to print all first-level directories on all drives together with their short 8.3 names:

Sub Main
        Dim fso As Scripting.FileSystemObject
        Dim dr As Scripting.Drive
        Dim fld As Scripting.Folder

        Set fso = New Scripting.FileSystemObject

        Debug.Clear
        On Error Resume Next
        For Each dr In fso.Drives
                If dr.IsReady Then
                        Debug.Print dr.RootFolder.Path
                        For Each fld In dr.RootFolder.SubFolders
                                Debug.Print "   " & fld.Path & " [ " & fld.ShortName & " ] "
                        Next fld
                End If
        Next dr
End Sub

 

Table 3 summaries the properties of the folder and file objects.

SyntaxApplies ToDescription
Attributes Folder and FileThe attributes of the file or the folder, as a combination of the following constants: 0-Normal, 1-ReadOnly, 2-Hidden, 4-System, 8-Volume, 16-Directory, 32-Archive, 64-Alias, 2048-Compressed
DateCreated Folder and FileCeation date (a read-only date value).
DateLastAccessed Folder and FileThe date of last access (a read-only date value.)
DateLastModified Folder and FileThe date of last modification (a read-only date value.)
Drive Folder and FileThe Drive object where the file or the folder is located.
Files Folder onlyThe collection of the contained File objects.
IsRootFolder Folder onlyTrue if this is the root folder for its drive.
Name Folder and FileThe name of the folder or file.
ParentFolder Folder and FileThe parent folder object.
Path Folder and FileThe path of the Folder or File (This is the default property)
ShortName Folder and FileThe name of the object in 8.3 MS-DOS format.
ShortPath Folder and FileThe path of the object in 8.3 MS-DOS format.
Size Folder and FileThe size in bytes of a file object; the sum of the size of all contained files and subfolders for a Folder object.
SubFolders Folder onlyThe collection of all the subfolders contained in this folder, including system and hidden ones.
Type Folder and FileA string description of the object. For example fs.GetFolder("C:\Recycled").type returns "Recycle Bin"; for File objects, this value depends on their extensions (for example, "Text Document" for a TXT extension.

Table 3 All the properties of Folder and File objects

The Folder object also exposes a few methods, summarized in Table 4. Note that you can often achieve similar results using appropriate methods of the main FSO object.

SyntaxDescriptionApplies To
Copy Destination [Overwrite]Folder and FileCopy the current File or the Folder object to another path; this is similar to the FSO's CopyFolder and CopyFile methods, which are also able to copy multiple objects in one operation
CreateTextFile (FileName,[Overwrite],[Unicode])Folder OnlyCrates a text file in the current folder and returns the corresponding TextStream object. See the corresponding FSO's method for an explaination of the individual arguments
Delete [Force]Folder and FileDelete this file or folder object (with all its contained subfolders and files). Similar to FSO's DeleteFile and DeleteFolder methods.
Move DistinationPathFolder and FileMove this file or folder object to another path; similar to FSO's MoveFile and MoveFolder methods.
OpenAsTextStream ([IOModel],[Format]) AsTextStreamFile onlyOpen this File object as a text file and return the corresponding TextStream object.

Table 4: All the methods of Folder and File objects.

You can also create a new Folder using the Add method applied to the SubFolders collection, as shown in the following recursive routine, which duplicates the directory structure of one drive onto another drive without also copying the contained files.

 ' Call this routine to initiate the copy process, the destination will be created if necessary.
Sub DuplicateDirTree(SourcePath As String, DestPath As String)
        Dim fso As Scripting.FileSystemObject
        Dim sourceFld As Scripting.Folder
        Dim destFld As Scripting.Folder

        Set fso = New Scripting.FileSystemObject

        ' The Source Folder Must Exist
        Set sourceFld = fso.GetFolder(SourcePath)

        ' The Destination folder is created if necessary.
        If fso.FolderExists(DestPath) Then
                Set destFld = fso.GetFolder(DestPath)
        Else
                Set destFld = fso.CreateFolder(DestPath)
        End If

        ' Jump to the recursive routine to do the copy.
        DuplicateDirTreeSub sourceFld, destFld

End Sub

Sub DuplicateDirTreeSub(source As Scripting.Folder, destination As Scripting.Folder)
        Dim sourceFld As Scripting.Folder
        Dim destFld As Scripting.Folder

        For Each sourceFld In source.SubFolders

                ' Copy this subfolder to the destination folder.
                Set destFld = destination.SubFolders.Add(sourceFld.Name)

                ' Then repeat the process for all the subfolders of the folder just considered.
                DuplicateDirTreeSub sourceFld, destFld

        Next sourceFld
End Sub


The File Object

The File object represents a single file on disk. You can obtain a reference to such an object in two ways:

  1. By using the GetFile method of the FSO object.

  2. By iterating over the Files collection of its parent Folder object.

Despite their different natures, File and Folder objects have many properties and methods in common, so I won't worry repeat the descriptions given in Tables 3 and 4.

A limitation of the FSO hierarchy is that you have no direct way to filter filenames using wildcards, as you can do with the Dir$ function. All you can do is iterate through the Files collection of a Folder object and test the file's name, extensions, or other attributes to see whether you are interested in it as shown in the following example.

 ' List all the DLL files in C:\WINDOWS\SYSTEM directory
Sub Main
        Dim fso As Scripting.FileSystemObject
        Dim fil As Scripting.File

        Debug.Clear
        Set fso = New Scripting.FileSystemObject
        For Each fil In fso.GetSpecialFolder(SystemFolder).Files
                If UCase$(fso.GetExtensionName(fil.Path)) = "DLL" Then
                        Debug.Print fil.Name
                End If
        Next fil
End Sub
 

The FileSystemObject hierarchy doesn't permit many operations on files. More specifically, while you can list their properties (including many properties that are beyond the current capabilities of native VB functions), you can open files only in text mode, as I explain in the next section.

The Text Stream Object

The TextStream object represents a file opened in text mode. You can obtain a reference to such an object in the following ways:

  1. By using CreateTextFile or the OpenTextFile method of the FSO object.

  2. By using the OpenAsTextStream method of a file object.

The TextStream object exposes a number of methods for read-only properties, all of which are described in Table 5. The TextStream object does offer some new features in addition to the regular VB file commands - for example, the ability to keep track of the current line and column while reading from or writing to the text file. This feature is exploited in this reusable routine that scans all the TXT files in a directory for a search string and returns an array of the results (actually, an array of arrays) with all the files that contain that search string as well as the line number and the column number to indicate the position of the string within the file:

 ' Code Module
Sub Main

        Debug.Clear

        ' An example use of the SearchTextFiles function
        Dim v() As Variant
        Dim i As Long
        v() = SearchTextFiles("C:\Documents and Settings\dupree\My Documents", "TEST_FAILED")
        For i = 1 To UBound(v)
                Debug.Print v(i)(0)&", [" & v(i)(1) & ", " & v(i)(2) & "]"
        Next i

End Sub

Function SearchTextFiles(Pathname As String, search As String) As Variant()
        Dim fso As Scripting.FileSystemObject
        Dim fldr As Scripting.Folder
        Dim fil As Scripting.File
        Dim ts As Scripting.TextStream
        Dim pos As Long
        Dim count As Long
        ReDim result(50) As Variant

        Set fso = New Scripting.FileSystemObject

        Set fldr = fso.GetFolder(Pathname)

        ' Search for all the TXT files in the directory.
        For Each fil In fldr.Files
                If UCase$(fso.GetExtensionName(fil.Path)) = "TXT" Then

                        ' Get the corresponding Text Stream object.
                        Set ts = fil.OpenAsTextStream(ForReading)

                        ' Read it's contents, search the string, close it.
                        pos = InStr(1, ts.ReadAll, search)
                        ts.Close

                        If pos > 0 Then
                                ' If the string has been found, reopen the file to determine string pos in terms of (line, col)
                                Set ts = fil.OpenAsTextStream(ForReading)

                                ' Skip all the preceding characters to get to where the search string is.
                                ts.Skip pos - 1

                                ' Fill the result array, maek room if necessary.
                                count = count + 1

                                If count > UBound(result) Then
                                        ReDim Preserve result(UBound(result) + 50) As Variant
                                End If

                                '  Each result item is a three element array.
                                result(count) = Array(fil.Path, ts.Line, ts.Column)

                                ' Now we can close the text stream.
                                ts.Close

                        End If
                End If
        Next fil

        ' Resize the result array to indicate number of matches.
        ReDim Preserve result(0 To count) As Variant
        SearchTextFiles = result
End Function


Running this code I get the following output in the debug window:

C:\Documents and Settings\dupree\My Documents\Example_Text.txt, [1, 1]
C:\Documents and Settings\dupree\My Documents\Example_Text2.txt, [1, 20]

Which indicates that two files were found with the string "TEST_FAILED" both on the first line but one at the start and one 20 characters into the line.

Property or MethodSyntaxDescription
PropertyAtEndOfLineTrue if the file pointer is at the end of the current line.
PropertyAtEndOfFileTrue if the file pointer is at the end of file (similar to VB's EOF function)
MethodCloseCloses the file (similar to VBs Close statement)
PropertyColumnCurrent column number
PropertyLineCurrent line number
MethodRead(Characters)Reads a specified number of characters and returns a string (similar to VB's Input$ function)
MethodReadAllReads the entire file into a string (similar to VB's $Input function when used with the LOF function)
MethodReadLineReads the next line of text and returns a string (similar to VB's Line Input statement)
MethodSkip CharactersSkips over a specified number of characters
MethodSkipLineSkips over a line of text
MethodWrite TextWrites a string of characters, without a trailing Newline character (similar to Print# command with a trailing semicolon
MethodWriteBlankLines LinesWrites an indicated number of blank lines (similar to one or more Print# commands without any argument)
MethodWriteLine [Text]Writes a string of characters, with a trailing Newline character (similar to the Print# command without a trailing semicolon

Table 5: All the properties and methods of the TextStream object.

Summary

So that completes this overview of the FileSystemObject object hierarchy provided by the Microsoft Scripting Library. The FileSystemObject provides modern, coherent and object-oriented way to work with Drives, Folders and Files which helps to make your code cleaner, more readable and easier to maintain.