Community Documents

cancel
Showing results for 
Search instead for 
Did you mean: 

Scan drives, directories, and files in a directory with AWR Scripting

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.

api_filesystemobject_object_hierarchy.png

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.

api_references_toolbar_button.png

api_references_dialog.png
  (A) Select the References Toolbar Button    (B) References Dialog Select the Microsoft Scripting Runtime 

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.

Syntax                           Description                                                                                      
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 Folder Creates a new Folder object and returns it; raises an error if the folder already exists
CreateTextFile(FileName,[Overwrite],[Unicode]) As TextStream Creates a new TextFile object and returns it; set Overwrite = False to avoid overwriting existing file; set Unicode = 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 Drive Returns 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 Folder Returns 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 Folder Returns 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 TextStream Opens 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 the VolumeName 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.

Syntax Description
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 or GetSpecialFolder 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.

Syntax Applies To Description
Attributes       Folder and File The 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 File Ceation date (a read-only date value).
DateLastAccessed Folder and File The date of last access (a read-only date value.)
DateLastModified Folder and File The date of last modification (a read-only date value.)
Drive            Folder and File The Drive object where the file or the folder is located.
Files            Folder only     The collection of the contained File objects.
IsRootFolder     Folder only     True if this is the root folder for its drive.
Name             Folder and File The name of the folder or file.
ParentFolder     Folder and File The parent folder object.
Path             Folder and File The path of the Folder or File (This is the default property)
ShortName        Folder and File The name of the object in 8.3 MS-DOS format.
ShortPath        Folder and File The path of the object in 8.3 MS-DOS format.
Size             Folder and File The size in bytes of a file object; the sum of the size of all contained files and subfolders for a Folder object.
SubFolders       Folder only     The collection of all the subfolders contained in this folder, including system and hidden ones.
Type             Folder and File A 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 File Copy 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 Only  Crates 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 File Delete this file or folder object (with all its contained subfolders and files). Similar to FSO's DeleteFile and DeleteFolder methods.
Move DistinationPath Folder and File Move this file or folder object to another path; similar to FSO's MoveFile and MoveFolder methods.
OpenAsTextStream([IOModel],[Format]) As TextStream File only Open 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 Method Syntax Description
Property AtEndOfLine True if the file pointer is at the end of the current line.
Property AtEndOfFile True if the file pointer is at the end of file (similar to VB's EOF function)
Method   Close       Closes the file (similar to VBs Close statement)
Property Column      Current column number
Property Line        Current line number
Method   Read(Characters) Reads a specified number of characters and returns a string (similar to VB's Input$ function)
Method   ReadAll     Reads the entire file into a string (similar to VB's $Input function when used with the LOF function)
Method   ReadLine    Reads the next line of text and returns a string (similar to VB's Line Input statement)
Method   Skip Characters Skips over a specified number of characters
Method   SkipLine    Skips over a line of text
Method   Write Text  Writes a string of characters, without a trailing Newline character (similar to Print# command with a trailing semicolon
Method   WriteBlankLines Lines Writes an indicated number of blank lines (similar to one or more Print# commands without any argument)
Method   WriteLine [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.

Contributors