VB6 S File System Objects
VB6 S File System Objects
by Peter G. Aitken File System Objects (FSO) completely recast Visual Basics fundamental powers over disk storage in an object-oriented mold. It makes file access and management considerably easier, even though it isnt quite complete. Ill take an in-depth look at one of the new toys that the Redmondians have provided in VB6: the object-oriented file access and management system, called File System Objects (FSO). This isnt one of the flashier additions to the new version of Visual Basic, and it certainly has not gotten the same attention as, say, ActiveX Data Objects or Dynamic HTML. Even so, its an important improvement to the language, one that you should begin using in your own programs as soon as possible. FSO really doesnt let you do anything that cannot be done with the old file-oriented commands, but it makes many tasks much easier. Perhaps most important is that FSO moves file access and manipulation from the realm of procedural programming to the modern realm of object-oriented programming, with all the advantages that entails. There is, however, one fly in the ointment. While the FSO framework for file management (creating folders, moving and deleting files, and so on) seems to be complete, the file access part of FSO (writing data to and reading data from files) is only partially complete. To be precise, you can read and write only sequential text filesfor random access and binary files, you are still limited to the traditional Basic statements. I am sure this limitation will be corrected soon, but for now youll just have to live with it. Some of the material in this column is adapted from my newest Coriolis Group book, Visual Basic 6 Programming Blue Book.
The Scripting qualifier identifies the library in which the FileSystemObject class is defined. To use the class, you do not need to select the Microsoft Scripting Runtime library in the Visual Basic References dialog box, but doing so will give you access to the classes, methods, and properties in the Object Browser. (If you are not familiar with the Object Browser, you owe it to yourself to find out; it is a great source of information about classes.) After creating an instance of the FileSystemObject class, the next step is to create a TextStream object. A TextStream object is nothing more than a regular text file enclosed in an FSO wrapper. The FileSystemObject has two methods for creating TextStream objects:
CreateTextFile creates a new text file. If a file of the same name already exists, it is overwritten. OpenTextFile opens a text file for reading and/or writing. If the file already exists, new data is appended to existing data.
The syntax for these methods is similar. In these examples, assume that myFSO is a FileSystemObject and that it has been declared as a type Variant or Object. The first line of code creates a new file, and the second line opens an existing file:
Set ts = myFSO.CreateTextFile(filename[, overwrite[, unicode]])
Set ts = myFSO.OpenTextFile(filename[, iomode[, create[,format]]])
Filename is a string expression specifying the name (including path information) of the file. The overwrite argument is either True or False, indicating whether an existing file will be overwritten. If this argument is omitted, the default is False. If overwrite is False and filename already exists, an error occurs. You can trap this error to permit the user to verify file overwrites. Set unicode to True to create a Unicode file, or False (the default) for an ASCII file. Set iomode to the constants ForReading or ForAppending to read the file or write data to the end of the file, respectively. A file opened using ForReading cannot be written to. Set create to True or False to specify whether a new file will be created if the file named in the filename argument does not exist. The default is False. The format argument is a tristate argument (that is, one that can take on one of three possible values) that determines the format of the file:
TriStateTrue opens the file as Unicode. TriStateFalse (the default) opens the file as ASCII. TristateUseDefault uses the system default format setting.
What Is Unicode? When dealing with text, computers use numbers to represent characters, punctuation marks, and so on. The two most commonly used systems for this are ASCII (or ANSI) and Unicode. ASCII uses one byte per character, permitting only 256 different symbols to be represented. This is adequate for English but cannot support many other languages. Unicode uses 2 bytes per character, permitting over 65,000 different symbols. Which format you use depends on the specific requirements of your project.
Another way to obtain a TextStream object is to create a File object and then use its OpenAsTextStream method. This method works with existing files only. Creating a File object is done like this, assuming that myFSO is a FileSystemObject:
Dim f
Set f = myFSO.GetFile(filename)
If the file does not already exist, you can take the following approach, using CreateTextFile to create the file before creating the File object:
myFSO.CreateTextFile filename
Set f = myFSO.GetFile(filename)
After creating the File object, you can invoke the Open-AsTextStream method. The syntax is:
f.OpenAsTextStream([iomode, [format]])
The iomode and format arguments are the same as described above for the CreateTextFile and OpenTextFile methods. Heres the code necessary to create a TextStream object associated with an existing file DEMO.TXT for reading, using the OpenAsTextStream method:
Dim myFSO, f, ts
Set myFSO = CreateObject("Scripting.FileSystemObject")
Set f = myFSO.GetFile("demo.txt")
Set ts = f.OpenAsTextStream(ForWriting, _ TristateUseDefault)
Once you have created a TextStream object, you use its properties and methods to write and read text. The objects properties are listed in Table 1. In reading this table, be aware that the TextStream object always has a current character position, also called the file pointer, that indicates where the next read or write operation will take place. All of these properties are read-only. Table 1. Properties of the TextStream object. Property Description True if the file pointer is at the end of a line; False AtEndOfLine otherwise. This property applies only to TextStream files that are open for reading; otherwise, an error occurs. True if the file pointer is at the end of the file; False AtEndOfStrea otherwise. This property applies only to TextStream files m that are open for reading; otherwise, an error occurs. Column Line Returns the column number of the file pointer. The first character on a line is at column 1. Returns the current line number.
The TextStream object has a number of methods to read and write data. These methods are described in Table 2. Table 2. Methods of the TextStream object. Property Close Read(n) ReadAll ReadLine Skip(n) SkipLine Write(s) Description Closes the file associated with the TextStream object. Always execute the Close method when you are done reading/writing the file. Reads the next n characters from the file and returns the resulting string. Reads the entire file and returns the resulting string. Reads an entire line (up to, but not including, the newline character) from a TextStream file and returns the resulting string. Skips ahead (moves the file pointer) by n characters. Skips to the beginning of the next line. Writes the string s to the file. No extra or newline characters are added.
WriteBlankLines Writes n blank lines to the file. (n) WriteLine(s) Writes the string s to the file followed by a newline character.
Be aware that certain of these methods are applicable only when the file has been opened for reading or writing. If you try to use a method that is inappropriate for the files mode, an error will occur.
Drive object, which corresponds to a single disk drive on the system. Folder object, which corresponds to a single folder on a drive. File object, which corresponds to a single file in a folder.
The following is a brief overview of how the FSO system works. The FileSystemObject has a Drives collection that contains one Drive object for each local and network drive. You can query a Drive objects properties to obtain information about the drive, such as its type and the amount of free space. Each Drive object contains a single Folder object representing the drives top-level folder, or root. Each Folder object contains a Folders collection and a Files collection. The Folders collection contains a Folder object for each subfolder within the folder, and the Files collection contains a File object for each file in the folder. The Drives, Folders, and Files collections are like any other Visual Basic collection, and they are used the same way. (I cant explain collections here, but its a good idea for you to understand them because they are used a lot in Visual Basics objects.) Each Drive object has a set of properties (listed in Table 3) that provides information about the physical drive. Except as noted, these properties are all read-only.
Property
Description
The amount of space available to a user on the specified AvailableSpa drive or network share. Generally the same as the ce FreeSpace property, but may differ on systems that support quotas. DriveLetter The drive letter associated with the drive. Returns a zerolength string for network drives that have not been mapped to a drive letter. A value indicating the type of the drive. Possible values are 0 (unknown), 1 (removable), 2 (fixed), 3 (network), 4 (CDROM), and 5 (RAM disk). The type of file system. Available return types include FAT, NTFS, and CDFS. The amount of space available to a user on the specified drive or network share. Generally the same as the AvailableSpace property, but may differ on systems that support quotas. Returns True if the drive is ready, False if not. Used with removable media and CD-ROM drives, returning False if the media has not been inserted. The path of the drive. This consists of the drive letter followed by a colon. Returns a Folder object representing the drives root path.
DriveType FileSystem
FreeSpace
The unique serial number identifying a disk. Use this SerialNumbe property to verify that a removable media drive contains the r proper media. ShareName TotalSize The share name assigned to a network drive. For nonnetwork drives, a zero-length string. The total capacity of the drive.
VolumeNam The volume name of the drive. You can write to this e property to change a drives volume name. A simple program can demonstrate how to use the Drives collection to obtain information about the drives on the system. Create a Standard EXE project and place a Text Box on the form. Set the Text Boxs Multiline property to True, and set its size to nearly fill the form. Put the code from Listing 1 in the Text Boxs Click event procedure. When you run the program, click on the Text Box control to display a list of the systems drives and their total and free space.
A Folder object represents a single folder, or subdirectory, on a drive. You use the objects methods to copy, move, or delete the folder (as explained below), and you use the objects properties to obtain information about the folder. Perhaps most important, a Folder object contains two collections, Files and SubFolders, that provide access to the files and subfolders within the folder. Table 4 explains the properties of the Folder object. Table 4. Properties of the Folder object. Property DateCreated Description Date and time the folder was created.
DateLastAcces Date and time the folder was last accessed. sed DateLastModifi Date and time the folder was last modified. ed Drive Files IsRootFolder Name ParentFolder Path ShortName ShortPath Size SubFolders Drive letter of the drive where the folder resides. A Files collection containing all the files in the folder. True if the folder is the root, False otherwise. Sets or returns the name of the folder. Returns a Folder object representing the folders parent folder. The path of the folder, including drive letter. The short name used by programs that require the old 8.3 naming convention. The short path used by programs that require the old 8.3 naming convention. The size, in bytes, of all files and subfolders contained in the folder. A Folders collection containing one Folder object for each subfolder.
Because each Folder object contains information about its parent folder and its subfolders, you can easily traverse the entire folder structure on a drive. This is a powerful tool, as will be demonstrated later. First, however, lets look at the Folder objects methods. The Copy method copies the folder and its contents to a new location. The syntax is as follows (assuming f to be a Folder object):
f.Copy destination[, overwrite]
The destination argument specifies the destination where the folder is to be copied to. Set overwrite to True (the default) to overwrite existing files or folders, or to False otherwise. Note that you can also copy a folder using the FileSystemObjects CopyFolder method. The Move method moves the folder and its contents from one location to another. The syntax is:
f.Move destination
Here, destination specifies the destination where the folder is to be moved to. You can also move folders with the FileSystemObjects MoveFolder method. The Delete method deletes a folder and its contents. The syntax is:
f.Delete [force]
The optional force argument specifies whether files or folders with the read-only attribute set should be deleted (force = True) or not (force = False, the default). You can also delete folders with the FileSystemObjects DeleteFolder method. To demonstrate the power of the Folder object, I created a small utility that counts the total number of files and folders on your C drive. This might seem like a difficult task, but it requires relatively little code. The simplicity of this program is a result of two things: the design of the Folder object and the use of a recursive algorithm. Heres an outline of how it works: 1. Get the drives root Folder object. 2. Use the root folders Folders collection to access each of its subfolders. 3. Determine the number of files and subfolders in each subfolder, and add these values to the totals. 4. Use the subfolders Folders collection to access each of its subfolders. 5. Continue until all subfolders have been processed. Create a standard EXE project with a single form. Place one Label control and a control array of two Command Buttons on the form. Set the Labels Caption property to a blank string, and the Command Buttons Caption properties to Start and Quit. Place the following global variable declarations in the General section of the forms code:
These variables will hold the counts of files and folders. Generally speaking, its not good programming practice to use global variables such as these, but for such a simple program, it simplifies our job and will not cause any problems. Next, place the code shown in Listing 2 in the Command Buttons Click event procedure. When the user clicks on the Start button, this code does the following: 1. Initializes the counter variables to 0. 2. Disables the Command Buttons so they cannot be clicked while the counting process is in progress. 3. Displays Working in the Label control. 4. Calls the procedure CountFilesAndFolders (yet to be written) to perform the count. 5. When execution returns from the procedure, re-enables the Command Buttons. The process of counting the files and folders is performed by the procedure CountFilesAndFolders. To be more accurate, the counting process is started by this procedure. The code is shown in Listing 3. Heres what the code does: 1. Creates a FileSystemObject. 2. Loops through the Drives collection until drive C: is found. 3. Passes the drives RootFolder, which youll remember is a Folder object, to the procedure DoCount. The real work of the program is done by the DoCount procedure, shown in Listing 4. Given how much work it does, it is deceptively short. It is here that the power of the recursive algorithm comes into play. DoCount is passed a Folder object as its argument. Then, heres what it does: 1. Gets the number of subfolders in the folder and adds it to the folders count. 2. Gets the number of files in the folder and adds it to the files count. 3. Calls DoCount for each subfolder in the Folders collection. Step 3 is where the recursion occurswhen the DoCount procedure calls itself. As this program illustrates, recursion can be a powerful technique for certain tasks. If you dont believe me, try to write a program that counts the files and folders on a drive without using recursion.
Now lets turn our attention to the final member of the FSO team, the File object. In the FSO model, each file on a disk is represented by a File object. There are two ways to create a File object. If you know the name and path of the file, you can use the FileSystemObjects GetFile method. Assuming that fs is an instance of the FileSystemObject class:
Dim f
Set f = fs.GetFile(filespec)
The argument filespec contains the filename, including a relative or absolute path. An error occurs if the file called out in filespec does not exist. Note that executing GetFile does not open the file, it simply returns a File object linked to the file. Another way to obtain a File object is from a Folder objects Files collection. As you learned earlier, you can create a Folder object for any subfolder on a disk, and the Folder object contains a Files collection containing one File object for each file in the folder. You can write code to iterate through the collection, looking for one or more files that meet a specified criterion. For example, the following code creates an array of File objects containing all the DLL files in the applications current path:
Dim fs, f, f1, filelist()
Dim i As Integer, j As Integer i = 0 ReDim filelist(0) Set fs = CreateObject("Scripting.FileSystemObject") Set f = fs.GetFolder(App.Path) For Each f1 In f.Files If LCase(Right(f1.Name, 3)) = "dll" Then i = i + 1 ReDim Preserve filelist(i) Set filelist(i) = f1 End If Next
Once you create a File object, you have access to all the properties of the file. You can also use the objects methods for certain types of file manipulation. The methods and properties are explained in Tables 5 and 6. Table 5. The File objects methods. Method Copy dest [, overwrite] Move dest Delete [force] Description Copies the file to dest. An existing file is overwritten only if overwrite is True (the default). Moves the file to dest. Deletes the files. Read-only files are deleted only if
10
force is True. The default is False. OpenAsTextStrea Opens the file and returns a TextStream object. m Attribute s Table 6. The File objects properties. Property Attributes DateCreated Description Returns a value summarizing the files attributes, as explained in detail below. Date and time the file was created.
DateLastAcces Date and time the file was last accessed. sed DateLastModifi Date and time the file was last modified. ed Drive Name ParentFolder Path ShortName ShortPath Size Type Drive letter of the drive where the file resides. Sets or returns the name of the file. Returns a Folder object representing the files parent folder. The path of the file, including drive letter. The short filename used by programs that require the old 8.3 naming convention. The short path used by programs that require the old 8.3 naming convention. The size, in bytes, of the file. Returns information about the type of the file.
The Attributes property provides information about the files attributes, such as whether it is read-only or a system file. The single value returned by the Attributes property is a composite of the individual attribute values, as shown in Table 7. This table also indicates which of the individual attributes are read/write and which are read-only. You use Visual Basics logical operators to convert between individual file attributes and the value of the Attributes property. Table 7. Component values of the Attribute property. Attribute Normal ReadOnly Valu Description e 0 1 Normal file; no attributes are set Read-only file Read/writ e 11 Access
2 4 8
Hidden file System file Disk drive volume label File has changed since last backup
16 Folder or directory 32
Even though it will take a lot of getting used to, the FSO approach to file access and management is a great improvement over the old methods. Once FSO is expanded to include random access and binary files, youll be able to relegate the traditional Basic file-related statements to the dustbin of history. During daylight hours, Peter is a research scientist at Duke University Medical Center in Durham, North Carolina. Comments and suggestions may be sent to him at [email protected]
12