五、文件系统对象(FileSystemObject)编程
1、File System Object 模型介绍
Visual Basic 的一个新功能是 File System Object (FSO) 对象模型,该模型提供了一个基于对象的工具来处理文件夹和文件。这使您除了使用传统的Visual Basic 语句和命令之外,还可以使用您所熟悉的带有一整套属性、方法和事件的 object.method 语法来处理文件夹和文件。
FSO 对象模型使应用程序能够创建、改变、移动和删除文件夹,或者检测是否存在指定的文件夹,如果存在,在哪。FSO 对象模型也能使您获取关于文件夹的信息,诸如名称、创建日期或最近修改日期等等。FSO 对象模型也使得对文件的处理变得更加简单。在处理文件时,首要目标就是以一种可以有效利用空间和资源、并且易于存取的格式来存储数据。需要能够创建文件、插入和修改数据、以及输出(读)数据。虽然可以将数据存储在诸如 Jet 或 SQL 这样的数据库中,但是这样做将在应用程序中加入相当数量的额外开支。出于多种原因,您不想有这样的额外开支,或者数据存取要求不需要用一个与全功能数据库关联的所有额外功能。在这种情况下,用二进制或文本文件来存储数据是最有效的解决方法。包含在 Scripting 类型库 (Scrrun.Dll) 中的FSO 对象模型支持通过TextStream 对象创建和操作文本文件。但是,它还不支持二进制文件的创建和操作。要操作二进制文件,请使用带 Binary 标志的 Open 命令(关于如何操作二进制文件的详细信息已在前面介绍过,请参阅)。
2、文件系统对象(File System Object)
FSO对象模型包括这些对象:
对象 |
描述 |
Drive |
允许收集关于系统所用的驱动器的信息,诸如驱动器有多少可用空间,其共享名称是什么,等等。请注意,一个“驱动器”并不一定是一个硬盘。它可以是 CD-ROM 驱动器、一个RAM 盘等等。而且,驱动器不一定是和系统物理地连接;也可以通过一个 LAN进行逻辑地连接。 |
Folder |
允许创建、删除或移动文件夹,并向系统查询文件夹的名称、路径等。 |
Files |
允许创建、删除或移动文件,并向系统查询文件的名称、路径等 |
FileSystemObject |
该组的主要对象,提供一整套用于创建、删除、收集相关信息、以及通常的操作驱动器、文件夹和文件的方法。与本对象相关联的很多方法复制了其它对象中的方法。 |
TextStream |
允许您读和写文本文件。 |
关于 FSO 对象模型中各种属性、方法和事件的信息,请使用 Visual Basic 中的“对象浏览器”(按 F2 键)并查看 Scripting 类型库。
FSO对象模型包含在一个称为Scripting的类型库中,此类型库位于Scrrun.DII文件中。如果还没有引用此文件,从“工程”菜单的“引用”对话框选择"Microsoft Scripting Runtime "项。然后就可以使用"对象浏览器"来查看其对象、集合、属性、方法、事件以及它的常数。
3、FSO 对象模型编程
FSO对象模型编程包括三项主要任务:
下面分别说明。
(1)创建 FileSystemObject 对象
第一步是创建一个 FileSystemObject 对象以便进行处理。可以通过如下两种方法完成:
在上面的语法中, Scripting 是类型库的名称,而 FileSystemObject 则是想要创建一个实例的对象的名称。
注意:第一种方法只在 Visual Basic 中有效,而第二种方法在 Visual Basic或 VBScript 中都是可行的。
(2)使用适当的方法
下一步就是使用该 FileSystemObject 对象的适当方法。例如,如果想要创建一个新对象,既可以使用 CreateFolder 方法也可以使用 CreateTextFile 方法(FSO 对象模型不支持创建或删除驱动器)。如果想要删除对象,可以使用 FileSystemObject 对象的 DeleteFile 和DeleteFolder 方法,或者 File 和 Folder 对象的 Delete 方法。使用适当的方法,还可以复制、移动文件和文件夹。
请注意,FileSystemObject 对象模型中有一些功能是冗余的。例如,要复制一个文件,既可以使用 FileSystemObject 对象的 CopyFile 方法,也可以使用 File 对象的 Copy 方法。这两者的功能是完全相同的。两者同时提供最大的编程灵活性。
(3)访问已有的驱动器、文件和文件夹
要访问一个已有的驱动器、文件或文件夹,请使用 FileSystemObject 对象中相应的 "get" 方法:
-
GetDrive
-
GetFolder
-
GetFile
例如:
Dim fso As New FileSystemObject, fil As File
Set fil = fso.GetFile("c:\test.txt")
但是,请注意,并不需要对新创建的对象使用"get" 方法,因为"create" 函数已经返回了一个句柄到新创建的对象。例如,如果使用 CreateFolder 方法创建了一个新的文件夹,就没有必要使用 GetFolder 方法来访问该对象的诸如名称、路径、大小等属性。只要给 CreateFolder 函数设置一个变量来获取新建文件夹的句柄,然后就可以访问其属性、方法和事件:
Private Sub Create_Folder() Dim fso As New FileSystemObject, fldr As Folder Set fldr = fso.CreateFolder("C:\MyTest") MsgBox "Created folder: " & fldr.Name End Sub
(4)访问对象的属性
一旦有了对象的句柄,就能够访问其属性。例如,假定想要获得一个特定文件夹的名称。首先要创建该对象的一个实例,然后通过适当的方法(在本例中是 GetFolder 方法,因为该文件夹已经存在)得到其句柄:
Set fldr = fso.GetFolder("c:\")
现在有了一个 Folder 对象的句柄,可以查看其 Name 属性:
Debug.Print "Folder name is: "; fldr.Name
如果想要找出一个文件的最新修改时间,可以使用如下的语法:
Dim fso As New FileSystemObject, fil As File
Set fil = fso.GetFile("c:\detlog.txt") '获得要查询的 File 对象。
Debug.Print "File last modified: "; fil.DateLastModified '打印信息。
(5)使用驱动器和文件夹
可以在程序中使用 FSO 对象模型来处理驱动器和文件夹,如同在“Windows资源管理器”中能进行的交互方式一样。可以复制和移动文件夹,获得驱动器和文件夹的信息,等等。
1)获得驱动器的信息
Drive 对象允许获得一个系统的各个驱动器的信息,这些驱动器可以是物理的,也可以是位于网络上的。通过该对象的属性可以获得下列信息:
-
以字节表示的驱动器总空间 (TotalSize 属性)
-
以字节表示的驱动器可用空间 (AvailableSpace 或 FreeSpace 属性)
-
为驱动器指定的字母号 (DriveLetter 属性)
-
驱动器类型,诸如可移动的、固定的、网络、CD-ROM、或者 RAM 盘(DriveType 属性)
-
驱动器序列号 (SerialNumber 属性)
-
驱动器使用的文件系统类型,诸如 FAT、 FAT32、 NTFS等等 (FileSystem属性)
-
驱动器是否可用 (IsReady 属性)
-
共享和/或卷标的名称 (ShareName 和 VolumeName 属性)
-
驱动器的路径或根文件夹 (Path 和 RootFolder 属性)
2)Drive 对象用法示例
下列示例说明了如何使用 Drive 对象来收集有关驱动器的信息。请记住,在下面的代码中并没有对一个实际 Drive 对象的引用;而是使用 GetDrive方法来获得一个对已有 Drive 对象(本例中就是 drv)的引用:
Private Sub Command3_Click() Dim fso As New FileSystemObject, drv As Drive, s As String Set drv = fso.GetDrive(fso.GetDriveName("c:")) s = "Drive " & UCase("c:") & " - " s = s & drv.VolumeName & vbCrLf s = s & "Total Space: " & FormatNumber(drv.TotalSize / 1024, 0) s = s & " Kb" & vbCrLf s = s & "Free Space: " & FormatNumber(drv.FreeSpace / 1024, 0) s = s & " Kb" & vbCrLf MsgBox s End Sub
3)使用 CurDir、 ChDrive、 ChDir 或 App.Path
如果使用 CurDir 函数、ChDrive 和ChDir 语句、或者 Path 属性(App.Path),请注意,它们返回的有可能是一个 UNC 路径(即,形如\\Server\Share而不是一个驱动器路径(如 E:\Folder),这取决于运行程序或工程的方式。
在如下的情况,App.Path 返回一个 UNC 路径:
ChDrive 不能处理 UNC 路径,因此当 App.Path 返回一个 UNC 路径给ChDrive 时,就会产生一个错误。要避免这个错误,可以在 ChDrive 语句之前添加 On Error Resume Next,或者测试 App.Path 的头两个字符是否是反斜杠:
On Error Resume Next
ChDrive App.Path
ChDir App.Path
这个改动将处理所有使用 UNC 路径从 Windows 启动程序(例如,在“启动”菜单的“运行”对话框中)的情况,因为 Windows 将当前的目录设为一个 UNC 路径。ChDir 可以正确地处理 UNC 路径之间的转换(ChDrive的失效可以被忽略,因为 UNC 路径当中没有驱动器号)。
然而,如果在 MS-DOS 的命令行提示符后键入一个 UNC 路径来运行程序的话,上面的代码不会生效。这是因为命令行提示符用的总是当前目录的驱动器路径,所以 CurDir 被设为一个驱动器路径。ChDir 不会产生错误,但是它不能将一个目录从驱动器路径变为 UNC 路径。在这种情况下,唯一的解决办法是定位一个已经映射为 UNC 路径中指定共享的本地驱动器,或者使用网络命令来创建这样一个映射。
如果工程是从一个网络共享——UNC 路径或映射的驱动器路径——加载到Visual Basic 集成开发环境(IDE)中的话,那么当运行工程时 App.Path 将返回一个 UNC 路径,而ChDrive 失败并产生一个错误。ChDir 虽然不会出错,但目录并未改变。唯一的解决办法是手工来设置驱动器和目录:
Const PROJECTSHARE = "E:\VBPROJ\MYPROJECT"
#Const Debug = True
#If Debug Then
ChDrive PROJECTSHARE
ChDir PROJECTSHARE
#Else
On Error Resume Next
ChDrive App.Path
ChDir App.Path
#End If
如果不止一个人可能在共享网络上打开该工程,那么可以使用一个 DOS 环境变量来允许每个人都拥有自己对该共享的映射:
#Const Debug = True
#If Debug Then
ChDrive Environ("MYPROJECTDIR")
ChDir Environ("MYPROJECTDIR")
#Else
On Error Resume Next
ChDrive App.Path
ChDir App.Path
#End If
MYPROJECTDIR 的值指定了被映射的驱动器号和路径,例如:
SET MYPROJECTDIR=M:\VBProj\MyProject
4)使用文件夹
下表显示了普通的文件夹任务以及完成这些任务的方法:
任务 |
方法 |
创建一个文件夹 |
FileSystemObject.CreateFolder |
删除一个文件夹 |
Folder.Delete 或FileSystemObject.DeleteFolder |
移动一个文件夹 |
Folder.Move 或FileSystemObject.MoveFolder |
复制一个文件夹 |
Folder.Copy 或FileSystemObject.CopyFolder |
检索文件夹的名称 |
Folder.Name |
查找一个文件夹是否在驱动器上 |
FileSystemObject.FolderExists |
获得已有Folder对象的一个实例 |
FileSystemObject.GetFolder |
找出一个文件夹的父文件夹的名称 |
FileSystemObject.GetParentFolderName |
找出系统文件夹的路径 |
FileSystemObject.GetSpecialFolder |
示例
该示例演示如何使用 Folder 对象和 FileSystemObject 对象来操作文件夹并获得其信息:
Private Sub Command10_Click() Dim fso As New FileSystemObject, fldr As Folder, s As String '获得 FileSystemObject 的实例。 Set fldr = fso.GetFolder("c:")'获取 Drive 对象。 Debug.Print "Parent folder name is: " & fldr '打印父文件夹名。 Debug.Print "Contained on drive " & fldr.Drive'打印驱动器名。 If fldr.IsRootFolder = True Then Debug.Print "This folder is a root folder." ' 打印根文件名。 Else Debug.Print "This folder isn't a root folder." End If fso.CreateFolder ("c:\Bogus") ' 用 FileSystemObject 对象创建一个新的文件夹。 Debug.Print "Created folder C:\Bogus" Debug.Print "Basename = " & fso.GetBaseName("c:\bogus")' 打印文件夹的基本名称。 fso.DeleteFolder ("c:\Bogus") '删除新建的文件夹。 Debug.Print "Deleted folder C:\Bogus" End Sub
(6)使用文件
通过使用新的面向对象的 FSO 对象,诸如 Copy、 Delete、 Move 以及OpenAsTextStream,或者使用传统的函数,诸如 Open、 Close、 FileCopy、GetAttr 等等,可以使用 Visual Basic 中的文件。请注意,不用考虑其文件类型就可以移动、复制或删除文件。
文件操作主要有两类:
- 创建、添加或移动数据,以及阅读文件
- 移动、复制和删除文件
1) 用FileSystemObject创建文件并添加数据
有三种不同方法来创建一个顺序文本文件(有时被称为“文本流”)。
一种方法就是使用 CreateTextFile 方法。要创建一个空文本文件,可以:
Dim fso As New FileSystemObject, fil As File
Set fil = fso.CreateTextFile("c:\testfile.txt", True)
另一种方法是使用 FileSystemObject 对象的 OpenTextFile 方法,该对象的ForWriting 标志设置为:
Dim fso As New FileSystemObject, ts As New TextStream
Set ts = fso.OpenTextFile("c:\test.txt", ForWriting)
或者使用带 ForWriting 标志设置的 OpenAsTextStream 方法:
Dim fso As New FileSystemObject, fil As File, ts As TextStream
Set fso = CreateObject("Scripting.FileSystemObject")
fso.CreateTextFile ("test1.txt")
Set fil = fso.GetFile("test1.txt")
Set ts = fil.OpenAsTextStream(ForWriting)
2)添加数据到文件
文本文件一经创建,就可以分三步向其中加入数据:
-
1. 打开文本文件以备写入数据。
-
2. 写入数据。
-
3. 关闭文件。
要打开文件,可以使用下面两种方法中的任一种: File 对象的OpenAsTextStream 方法,或 FileSystemObject 对象的 OpenTextFile 方法。要向打开的文本文件中写入数据,可以使用 TextStream 对象的 Write 或WriteLine 方法。它们之间的唯一差别是 WriteLine 在指定的字符串末尾添加换行符。
如果想要向文本文件中添加一个空行,请使用 WriteBlankLines 方法。
要关闭一个已打开的文件,请使用 TextStream 对象的 Close 方法。
下面这个例子示范了如何打开一个文件,使用上述三种写入方法向该文件中添加数据,然后关闭文件:
Sub Create_File() Dim fso, txtfile Set fso = CreateObject("Scripting.FileSystemObject") Set txtfile = fso.CreateTextFile("c:\testfile.txt", True) txtfile.Write ("这是一个测试例子。") ' 写入一行。 ' 写入一行带有换行符的文本。 txtfile.WriteLine("Testing 1, 2, 3.") ' 向文件中写入三个换行符。 txtfile.WriteBlankLines(3) txtfile.Close End Sub
3)使用 File System Objects 读取文件
要从一个文本文件中读取数据,请使用 TextStream 对象的 Read、 ReadLine或 ReadAll 方法:
任务 |
方法 |
从一个文件中读取指定数量的字符 |
Read |
读取一整行(紧跟,但不包括,换行符) |
ReadLine |
读取一个文本文件的所有内容 |
ReadAll |
如果使用 Read 或 ReadLine 方法并且想要跳过数据的某些部分,可以使用 Skip 或 SkipLine 方法。
这些读取方法产生的文本被存储在一个字符串中,而这个字符串可以在一个控件中显示,也可以被字符串操作符分解(诸如 Left、 Right 和 Mid)、合并等等。
注意:vbNewLine 常数包含一个或多个字符(取决于操作系统)使得光标移至下一行的开头(回车/换行)。请注意,有的字符串末尾可能有这样的非打印字符。
示例:
Sub Read_Files() Dim fso As New FileSystemObject, txtfile, fil1 As File, ts As TextStream Set txtfile = fso.CreateTextFile("c:\testfile.txt", True) MsgBox "正在写入文件" ' 写入一行。 Set fil1 = fso.GetFile("c:\testfile.txt") Set ts = fil1.OpenAsTextStream(ForWriting) ts.Write "Hello World" ts.Close ' 读取文件的内容。 Set ts = fil1.OpenAsTextStream(ForReading) s = ts.ReadLine MsgBox s ts.Close End Sub
4)移动、复制和删除文件
对文件的移动、复制和删除,FSO对象模型都 提供了两种方法,如表所示
任务 |
方法 |
移动 |
File.Move或FileSystemObject.MoveFile |
复制 |
File.Copy或FileSystemObject.CopyFile |
删除 |
File.Delete或FileSystemObject.DeleteFile |
示例:
本例先在C盘的根目录下创建了一个文本文件,并向其中写入一些信息,然后将该文件移至一个名叫 \tmp 的目录,并复制到一个叫 \temp 的目录下,最后删掉该文件在这两个子目录下的拷贝。
要运行本例,请先确认在C盘的根目录下已经存在名叫 \tmp 和 \temp 的目录。
Sub Manip_Files() Dim fso as New FileSystemObject, txtfile, fil1, fil2 Set txtfile = fso.CreateTextFile("c:\testfile.txt", True) MsgBox "写入文件" ' 写入一行。 txtfile.Write ("这是一个测试例子。") ' 关闭要写入的文件。 txtfile.Close MsgBox "移动文件到 c:\tmp" ' 获得C盘根目录下的一个文件句柄。 Set fil1 = fso.GetFile("c:\testfile.txt") ' 将该文件移至 \tmp 目录下。 fil1.Move ("c:\tmp\testfile.txt") MsgBox "复制文件到 c:\temp" ' 将该文件复制到 \temp 目录下。
fil1.Copy ("c:\temp\testfile.txt") MsgBox "删除文件" ' 获得这些文件当前位置的句柄。 Set fil1 = fso.GetFile("c:\tmp\testfile.txt") Set fil2 = fso.GetFile("c:\temp\testfile.txt") ' 删除这些文件。 fil1.Delete fil2.Delete MsgBox "全部完成!" End Sub
|