文本文件对于系统管理员来说是一个强大的系统管工具。这个对于现在的高级的图形界面和多用户的操作系统来说好象是不可能的。但是,简单的文本文件,比如 notepad 文件,仍然是系统管理的一个关键元素。文本文件是轻便而且便于维护的。他们占用较少的磁盘空间不需要其它多余的软件支持。文本文件可以简单的工作并且非常容易携带。用文本文件写的脚本文件可以被复制和察看任何计算机的信息,虽然它运行的系统不是 Windows.此外,它还提供了快捷,简单,标准的办法来向脚本输入和输出数据。文本文件可以存储向脚本中输入的数据arguments)或者向脚本中硬编码。这样你就不用向命令行中输入100个服务器的名字,脚本可以从文本文件中读这些信息。同样,文本文件为存储脚本获取的信息提供了快捷简单的方法。这些数据可以直接写到数据库,但是这个要求在服务器上作额外的配置,额外的脚本代码,在脚本运行时候额外的管理。但是数据可以存在文本文件中,然后在稍后导入到数据中去。FSO 提供一些读写文本文件的方法。
Creating Text Files
FSO 让你可以用现存在的文本工作,也可以让你自己创建脚本。为了创建一个新的文本文件,简单的创建一个 FSO 对象,然后调用 CreateTextFile 方法,输入完整的文件路径信息作为这个方法的参数。
例如,如下的脚本代码在文件夹 C:/FSO 中创建了一个 Scriptlog.txt 的文件:
1 Set objFSO = CreateObject("Scripting.FileSystemObject")
2 Set objFile = objFSO.CreateTextFile("C:/FSO/ScriptLog.txt")
如果这个文件存在,那么 CreateTextFile 方法会创建一个。如果这个文件已经存在,那么CreateTextFile 方法会复写存在的文本文件,而以新的空白的文件取代它。如果你希望这个文件不被取代,那么就用一个可以选择 Overwrite 的参数。当这个参数设置成 False 的时候,攒在的文件就不被复写。当这个参数被设置成 True(默认的是 True),那么就会复写存在的文件。例如,如下的脚本如果创建的文件存在的话就不会复写。
如果你将参数设置成False,并且文件存在,那么就会有一个运行的错误。因为如此,你可以检查文件是否存在,如果存在,那么就作其它的操作,例如允许用户更改一个新的文件名。
Creating File Names Within the Script
防止文件存在产生错误的方法是用脚本给文本文件生成一个名字。因为文件名字生成器并不创建一个有意义的名字,这对于你想在未来要命名的日志和其它文件来说不是一个好的办法。但是,这个对于需要临时文件的脚本来说保证了有个特定的文件名。例如,你或许想让你的脚本将数据保存在HTML 或者 XML 格式,然后将这些数据在 WEB 浏览器中显示,然后将这个临时文件在web 浏览器关掉时删除。在这种情况下,你可以用GetTempName 方法来生成一个特有的文件名。
为了生成一个特别的文件名,脚本首先要创建一个 FSO 对象实例然后调用 GetTempName 方法(不用参数。)例如在 4.33 中的脚本用一个 For Next 循环来随机生成 10 文件名字。
1 Set objFSO = CreateObject("Scripting.FileSystemObject")
2 For i = 1 to 10
3 strTempFile = objFSO.GetTempName
4 Wscript.Echo strTempFile
5 Next
用 GetTempName 来生成文件的名字生成的不是唯一的。部分原因是生成名称的算法,部 分是因为可能的名字的数量是有限的。文件名字被限制为 8 个字节,而且前三个字节规定为 rad,例如,你用脚本来创建 10000 个文件名字,在第 9894 个文件名字之后就不再是唯一的了,剩下的 106 个 53 对是复制的。
在 4.34 中的示例脚本用 GetTempName 方法来创建一个文件,脚本必须:
1. 创建一个 FSO 对象实例。
2. 创建一个给文件夹 C:/FSO 的变量叫做 strPath.
3. 用 GetTempName 方法来生成一个单独的文件名子。
4. 用 BuildPath 的方法来合并文件夹名字和文件名字来创建一个完成的临时文件的名字。这个 整个路径存储在 strFullName 变量中。
5. 调用 CreateTextFile 方法,用 strFullName 来作参数。
6. 在创建了这个文件之后,关闭这个文件。在生产环境中,大多数情况下,你可能要向里面写 了数据之后再关闭它。
1 Set objFSO = CreateObject("Scripting.FileSystemObject")
2 strPath = "C:/FSO"
3 strFileName = objFSO.GetTempName
4 strFullName = objFSO.BuildPath(strPath, strFileName)
5 Set objFile = objFSO.CreateTextFile(strFullName)
6 objFile.Close
Opening Text Files
用文本文件来工作有三个主要的步骤。在你可以作其它的事情之前,你必须打开文本文件。这个你可以打开存在的文件或者创建一个新的文本文件,创建结束之后,默认文件是打开的。每个方法都是返回一个TextStream 对象实例。
在你获得了 TextStream 对象之后,你可以向这个文件中写或者读这个文件。但是你不能向同一个文件读和写。换句话说,在同一个操作中,你不能打开一个文件,读这个文件然后再向这个文件中写东西。你必须读完这个文件后关闭,然后再打开这个文件,写入数据,然后关闭。
为了打开一个文本文件:
1. 创建一个 FSO 对象实例。
2. 用:OpenTextFile 来打开一个文本文件。这个 OpenTextFile 需要两个参数,一个是一个文 件的路径,另外一个是跟着的参数:
For reading (parameter value = 1, constant = ForReading).
文件被打开之后只是被用来为读作准备的,为了写这个文件,你必须再一次的打开文件,用参数 ForWriting 或者 ForAppending。
For writing (parameter value 2, constant = ForWriting).
文件被打开,并且写入的数据覆盖了原来存在的数据,就是说旧的数据被删除,新的被添加。用这个方法用新的数据来代替存在的数据。
For appending (parameter value 8, constant = ForAppending).
文件在这种模式下打开,并且新的数据添加到文件的末尾。用这个方法向存在的文件中添加新的数据。
当打开文件的时候,你必须使用适当的参数。当你用读的模式打开一个文件而试图向里面写东西的时候,你会收到一个 bad file mode
的错误。你如果试图打开一个非文本文件的话也会收到同样的错误的。你可以直接用数值(比如 1 代表写)或者创建一个常量然后赋值给它适当的值。例如,如下的两种方法都可以打开一个文件并且准备被读:
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:/FSO/ScriptLog.txt", ForReading)
Set objFile2 = objFSO.OpenTextFile("C:/FSO/ScriptLog2.txt", 1)
但是在没有定义这个常量的时候,你不能直接用。这是因为事实上 VB 脚本并没有这些 COM 对象常量。如下的脚本会返回一个 invalid procedure call or argument 的错误并且失败。这是因为ForReading 这个常量并没有显式的定义。因为它没有定义,所以这变量默认情况下被赋值为 0,而 0 对于 OpenTextFile 来说并不是一个合法的参数:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:/FSO/ScriptLog.txt", ForReading)
Listing 4.35 Opening a Text File for Reading
1 Const ForReading = 1
2 Set objFSO = CreateObject("Scripting.FileSystemObject")
3 Set objFile = objFSO.OpenTextFile("C:/FSO/ScriptLog.txt", ForReading)
Closing Text Files
所有的用脚本打开的文本文件在脚本结束的时候会自动关闭。因为如此,比不是必须的去显式的关闭一个文本文件。然而,关闭这个文本文件却是一个很好的程序实践并且在下面的一些情况下,如果不关闭文件的话,会产生一些错误。
Reread the file.
有些时候你或许希望用一个脚本多次读一个文件。你或许打开一个文本文件然后将它所有的内容全部保存给一个字符串变量,然后搜索这个字符串来查找特定的错误的代码。当这个错误找到了,你再逐行去读取文件,提炼出有错误的每一行。如果你尝试多次去读一个文件,你不会收到你期待的结果,而是会遇到一个运行的错误。例如下的脚本读取一个文本文件,返回文件的内容到屏幕,然后尝试重复这样的过程:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:/FSO/ScriptLog.txt", 1)
Wscript.Echo "Reading file the first time:"
strContents = objFile.ReadAll
Wscript.Echo strContents
Wscript.Echo "Reading file the second time:"
Do While objFile.AtEndOfStream = False
strLine = objFile.ReadLine
Wscript.Echo strLine
Loop
当在 cscript 下运行的是命令行的信息如下:
Reading file the first time:
File line 1.
File line 2.
File line 3.
Reading file the second time:
第一次文件是被读取的,内容存储在变量 strContents 上,第二次,文件读取的时候,没什有数据回显在屏幕上,这是因为文件已经到达了文件的末尾,没有其它的数据给你读了。为了读取这个数据,你必须关闭这个文件然后重新打开它。你不能在读到文件的末尾之后去跳到文件的开头去了。TextStreamObject.Close 方法用来关闭一个文本文件。例如,在 4.36 中的脚本创建一个FSO对象实例,然后打开一个文本文件,然后在立即关闭了。为了访问文件的内容,你必须再一次的调用 OpenTextFile 方法去重新打开这个文件。
Listing 4.36 Opening and Closing a Text File
1 Set objFSO = CreateObject("Scripting.FileSystemObject")
2 Set objFile = objFSO.OpenTextFile("C:/FSO/ScriptLog.txt", 1)
3 objFile.Close
Reading Text Files
在许多的企业脚本中,读取文本文件的内容是个标准进程,你可以用这个功能来读取命令行的参数。例如,你的文本文件包含了计算机名字的列表,脚本审计成读取这个列表,然后在每个计算机上运行这个脚本。搜索满足特定条件的日志文件。例如,你或许想找所有有错误的日志。将日志文件中添加内容并且汇入到数据库。例如,你或许有一个服务或者程序来保存信息到特定存文本文件格式。然后你用脚本来读取这个文件拷贝相关的信息到数据库中。
binary 文件格式的文件,比如 microsoft word 或者是 Microsoft excel .用 FSO读取文本文件的时候,只能有一种方式:从前到后。此外,FSO 读取文件的时候是逐行读取的。如果你试图返回前面的行,你必须从开始再重新读取,直到特定的行。
你不能打开一个文件同时用来读和写。如果你打开一个文件是为了读的,那么你想修改文件内容的时候,你必须重新打开文件。如果你尝试在写的模式下读取文件,那么你会收到一个bad file mode 的错误。
还有读取特定的字符然后停止也是我们常用的技巧。例如,如下的命令会读取第一行的前 12 个字符Alerter.Shar,并且将它赋值给变量
strText,然后停止:strText = objTextFile.Read(12)
ReadLine 读取文本文件中每行的信息然后在到达新的一行的之前停止。例如,如下的命令读取第一行并且将它赋值给变量strText,然后停止。strText = objTextFile.ReadLine
为了逐行读取整个文件的内容,将 ReadLine 放在一个循环中。
ReadAll Reads the entire contents of a text file into a variable.
Skip 跳过特定的数目的字符之后停止。例如,如下的命令面跳过前面的 12 字节,后操作都说从第 13 个字符开始。
objTextFile.Skip(12)
SkipLine 跳过一整行。例如,如下的代码先读第一行,然后读取第三行。跳过了第二行
strText = objTextFile.Readline
objTextFile.SkipLine