VBS脚本运行库手册之六 ——Dictionary 对象

Dictionary Object

脚本经常用来从外面的源获得信息,例如从文本文件或者数据库文件。在这些信息获得之后,它将被存储到它的内存中,然后用脚本来更改它。例如将信息存储在一个变量中,或者存储在一个数组中。同样,这些信息可以存储在Dictionary 对象中。Dictionary 就好象一个数组一样。不同的是,它用叫做键对(key-item pairs)来存储信息,而数组用数字值来存储。例如,一个一维的数组存储州的首府像下面这样:

0 - Olympia

1 - Salem

2 - Sacramento

于其相反,Dictionary 存储信息像如下的格式:

Washington – Olympia

Oregon - Salem

California - Sacramento

如果你的命令行只是要求输入一个参数,比如计算机名字,你可以用数组来完成这样的工作。但是,Dictionary 提供了比数组更加多的功能。特别指出的是,Dictionary 不要求一个脚本确定需要存储的元素的数目。在数组中,你必须确定数组的大小,或者当添加数据的时候重新变更数组的大小。知道每个值对应的 index。在Dictionary 中,值可以通过 key 或者 item 自身来访问。

这样,当管理员用脚本从外部获得信息,比如获得计算机的名字,然后存储在内存中以备使用的时候,Dictionary 就成了一个理想的工具。


Creating a Dictionary

因为 Dictionary 是一个 COM 对象,你必须用其它的 COM 对象那样去初始化它。如下的代码创建一个 Dictionary 对象。

Set objDictionary = CreateObject("Scripting.Dictionary")

当创建完了一个 Dictionary 对象之后,你可以配置 Dictionary 的属性或者向其内部添加元素。


Configuring Dictionary Properties

Dictionary 只有一个配置的属性,CompareMode,它对于要添加哪个 KEY 或者不能添加哪个 KEY起着非常重要的作用。(检查 key 是否存在在 Dictionary 中也是十分重要的)默认的情况下,Dictionary 是被创建成二进制模式,基于 ASCII 的值。知道这个很重要,因为在ASCII 中,大写和小写字符是不同的。在二进制中,如下的两个服务可以同时被添加进来:

alerter

ALERTER

换句话说,在二进制模式下,你可能因为大小写不同而添加进来很多个同样的 item。这样就难于搜索了。如果你想查找 Alerter 这个KEY,你可能得到它不存在,因为没有和它大小写完全一样的值。这样你可能向一个 Dictionary 添加同样的 item。当一个 Dictionary 被配置成text 模式的时候,大小写被认为是一样的,这样可以除去同样的 key,你的 Dictionary 如果存在 alerter 的话,你就不能向其中添加另外一个叫做 ALERTER 的 key。无论你搜索 alerter 还是 ALERTER,都会找到叫做 Alerter 的 key。

为了配置 Dictionary 的模式,首先创建一个 Dictionary 对象实例,然后配置它的属性为如下的值:

0-设置成为二进制模式,这个是默认选项。

1 – 设置成 text 模式。

例如,如下的 4.44 的脚本设置 Dictionary 成 text 模式:

Listing 4.44 Configuring the Dictionary Object

1 Const TextMode = 1

2   Set objDictionary = CreateObject("Scripting.Dictionary")

3   objDictionary.CompareMode = TextMode

在 Dictionary 有任何元素的时候,你不能更改 Dictionary 的 CompareMode 属性。这是因为,二进制允许大小写的区分,例如,如下的

keys 每个代表了不同 key,因为 Dictionary 是基于二进制格式的:

apple

Apple

APPLE

在 text 模式下,这些 keys 是一致的。如果你将这些元素存储在二进制格式,那么没有什么问题,但是存储在 text 模式下的时候,Dictionary

就突然之间有三个同样的 keys,它就会失败了。

如果你想配置 Dictionary 的模式,那么事先移走 Dictionary 中所有的元素。



Adding Key-Item Pairs to a Dictionary

在创建了 Dictionary 对象实例之后,你可以用 add 方法向 Dictionary 添加 key-item 对。Add方法需要两个参数,必须按照如下顺序并且用逗号分开:  Key name ,   Item value

例如,在脚本 4.45 中,创建了一个 Dictionary 对象,然后添加一些类似于表格 4.10 中的key-item 对。

Table 4.10 Sample Key-Item Pairs

Key Item

Printer 1 Printing

Printer 2Offline

Printer 3Printing

Listing 4.45 Adding Key-Item Pairs to a Dictionary

1   Set objDictionary = CreateObject("Scripting.Dictionary")

2   objDictionary.Add "Printer 1", "Printing"

3   objDictionary.Add "Printer 2", "Offline"

4   objDictionary.Add "Printer 3", "Printing"

Dictionary 的 key 必须是唯一的。例如,如下的两个语句会产生一个运行的错误出来。在第一行被编译之后,叫做 printer 1 的 key 已经存在于 Dictionary 中了:

objDictionary.Add "Printer 1", "Printing"

objDictionary.Add "Printer 1", "Offline"



Inadvertently Adding a Key to a Dictionary

使用 Dictionary 对象的一个潜在的问题是,你如果去访问一个在 Dictionary 中不存在的元素的时候,它不产生一个错误,而是将这个不存在的元素添加到 Dictionary 中去了。看下面的脚本示例,它创建了一个

Dictionary,添加了三对 key-item,然后尝试去回显不存在的item,printer 4:

Set objDictionary = CreateObject("Scripting.Dictionary")

objDictionary.Add "Printer 1", "Printing"

objDictionary.Add "Printer 2", "Offline"

objDictionary.Add "Printer 3", "Printing"

Wscript.Echo objDictionary.Item("Printer 4")

当脚本尝试去回显不存在的 item 的时候,没有任何运行错误发生,而是创建了一个新的 key,printer 4,并被添加到了 Dictionary 中,它的对象的 item 的值是 null。

为了避免这样的错误发生,在访问 item 的值的时候,去检查它是否存在。



Manipulating Keys and Items in a Dictionary

作为 Dictionary 本身而言,它的用途很少。一个 Dictionary 只有在访问它的 item,列举它的item,或者修改它的 item 的时候,才变得有用。在你创建了一个 Dictionary 之后,你可能作如下的一些事情:

确定在这个 dictionary 中有多少对 key-item 对列举出在 dictionary 的 keys 和或者 item。

决定在 Dictionary 是否存在特定的 key修改在 Dictionary 中的 key 或者 item 的值从 Dictionary 中移除特定 key-item 对。

所有这些任务都可以通过在 RunTime Library 中提供的属性方法来实现。



Determining the Number of Key-Item Pairs in a Dictionary

和其它的许多集合一样,Dictionary 有一个 count 属性用来返回在这个集合中的 key-item 对的数量。在脚本 4.46 中创建了是个

Dictionary 对象,然后添加三个 key-item 对,回显这个Dictionary 的 count 属性的值。

Listing 4.46 Determining the Number of Key-Item Pairs in a Dictionary

1  Set objDictionary = CreateObject(“Scripting.Dictionary”)

2    objDictionary.Add “Printer 1”, “Printing”

3    objDictionary.Add “Printer 2”, “Offline”

4    objDictionary.Add “Printer 3”, “Printing”

5    Wscript.Echo objDictionary.Count

当脚本运行的时候,会显示一个值 3



Enumerating Keys and Items in a Dictionary

Dictionary 被设计成用来暂时的存储信息。任何存在 Dictionary

中的信息都是作为临时用的,没有用来长期存储的。它一般是用来临时放信息,然后在脚本中在重新调用他们。例如,你有个存储了服务器名称清单的Dictionary,然后在后面的脚本中连到这些服务器上,并且获得相应的信息。结果是,你每次连接到一个服务器的时候,你都必须去调用 Dictionary中的信息。

Keys items 的方法可以用来返回他们的组成集合,或者的单独的返回或者全部返回在Dictionary 中的 item-key 的信息。在你用了其中的一个方法之后,你可以用 For Each 循环列举除在数组中所有的 key-item。

例如在 4.47 中的脚本创建一个简单的 Dictionary,添加三对 keys-item,在这个 Dictionary 创建结束之后,脚本用 keys 方法来列举出所有的 keys,然后用 items 方法来返回所有的 items

Listing 4.47 Enumerating Keys and Items in a Dictionary

1    Set objDictionary = CreateObject("Scripting.Dictionary")

2    objDictionary.Add "Printer 1", "Printing"

3    objDictionary.Add "Printer 2", "Offline"

4    objDictionary.Add "Printer 3", "Printing"

5

6    colKeys = objDictionary.Keys

7    For Each strKey in colKeys

8    Wscript.Echo strKey

9    Next

10

11   colItems = objDictionary.Items

12   For Each strItem in colItems

13   Wscript.Echo strItem

14   Next

当脚本在 CScript 下运行的时候,命令行的信息如下:

Printer 1

Printer 2

Printer 3

Printing

Offline

Printing

为了显示特定的 item 的值,用 item 方法,例如,如下的代码语句显示了 key 是 printer 3 的item 的值:

Wscript.Echo objDictionary.Item("Printer 3")




Verifying the Existence of a Specific Key

Dictionary 的一个比数组更加优秀和标准的优点是你可以快速的找到特定的 key 是否存在。例如,假如你有一定的文件 list 安装在一个计算机上,并且你向搜索这个 list,来保证特定的dll文件已经安装了。你用集合或者数组,除非你系统的搜索整个数组否则你没有方法来确定特定的一个文件是否存在了。但是用 Dictionary 你可以 Exists 方法来检查给定的 key 是否存在。用Exists 方法只是需要一个参数,(需要查询的 key 的名字),然后返回一个 Boolean 的值,如果是真的值,表明这个 key 存在,如果是否,则不存在。

例如,在脚本 4.48 中创建一个 Dictionary 对象,添加三对元素,然后脚本检查叫做 key 的关键词是否存在,并且回显其结果。

Listing 4.48 Verifying the Existence of a Dictionary Key

1 Set objDictionary = CreateObject("Scripting.Dictionary")

2   objDictionary.Add "Printer 1", "Printing"

3   objDictionary.Add "Printer 2", "Offline"

4   objDictionary.Add "Printer 3", "Printing"

5   If objDictionary.Exists("Printer 4") Then

6   Wscript.Echo "Printer 4 is in the Dictionary."

7   Else

8   Wscript.Echo "Printer 4 is not in the Dictionary."

9   End If

当脚本运行的时候,会有 printer 4 is not in the Dictionary 的消息出现在屏幕上.


Modifying an Item in a Dictionary

添加到 Dictionary 中的 item 不是一成不变的,事实上,你可以在任何的时间去更改它。这个功能可以让你纪录脚本的运行情况。例如,你的Dictionary 是个关于服务器名称的列表区,每次你的脚本对应的服务器运行结束之后,你可以更改它对应的 item 值来标识它的状态。在脚本中止之前,你可以将状态列出来看脚本运行成功与否的。在 4.49 中的脚本创建了一个具有三个 keys 的 Dictionary,这三个key 分贝为 atl-dc-01,atl-dc-02,atl-dc-03,每个的 item 都是设置成 no status,这个表明针对这个服务器的状态信息还没有获得。然后回显他们的 item的信息。

在这个 Dictionary 被创建之后,用 item 方法以 key 作为参数更改这些 item 的值。例如,如下的脚本代码语句更改 key  atl-dc-01 的 item 为 available::

objDictionary.Item("atl-dc-01") = "Available"

在这三个 items 的值被更改了之后,新的 item 被回显出在屏幕上:

Listing 4.49 Modifying the Value of a Dictionary Item

1Set objDictionary = CreateObject("Scripting.Dictionary")

2objDictionary.Add "atl-dc-01", "No status"

3objDictionary.Add "atl-dc-02", "No status"

4objDictionary.Add "atl-dc-03", "No status"

5

6colKeys = objDictionary.Keys

7For Each strKey in colKeys

8Wscript.Echo strKey, objDictionary.Item(strKey)

9Next

10

11    objDictionary.Item("atl-dc-01") = "Available"

12    objDictionary.Item("atl-dc-02") = "Available"

13    objDictionary.Item("atl-dc-03") = "Unavailable"

14

15    colKeys = objDictionary.Keys

16    For Each strKey in colKeys

17    Wscript.Echo strKey, objDictionary.Item(strKey)

18    Next

当在 Cscript 下运行这个的时候,命令行中的信息如下:

atl-dc-01 No status

atl-dc-02 No status

atl-dc-03 No status

atl-dc-01 Available

atl-dc-02 Available

atl-dc-03 Unavailable

Removing Key-Item Pairs from a Dictionary

Key-item 对也可以从 Dictionary 中移走,Script Runtime Library 提供了移走 key-item 对的两种方法:

   RemoveAll, 移走所有的 key-item 对

   Remove, 从 Dictionary 移走特定的 key-item 的值。



Removing All Key-Item Pairs from a Dictionary

你或许有一些脚本,比如监视的脚本,作着同样的动作,将信息存在一个 Dictionary 中,然后要么在屏幕上显示这些信息,要么将这些信息存储在文本文件中或者数据库中。然后,脚本停止几分钟,收集更新了之后的信息,就这样不确定的进行下去了。

如果你用 Dictionary 来作为临时的数据存储收集信息数据,你可能希望在收取新的信息之前清空 Dictionary 的内容。为了做到这点,你可以用方法RemoveAll 来移走所有的 Dictionary中的 key-item 对。例如,在 4.50 中的脚本创建了一个含有三个元素的 Dictionary,然后显示 Dictionary 的 keys,脚本用 RemoveAll 方法移走所有的 key-item对,Dictionary.RemoveAll 为了检查元素是否被移走,在此回显 Dictionary 中 key 的信息Listing 4.50 Removing All the Key-Item Pairs in a Dictionary

1    Set objDictionary = CreateObject("Scripting.Dictionary")

2    objDictionary.Add "Printer 1", "Printing"

3    objDictionary.Add "Printer 2", "Offline"

4    objDictionary.Add "Printer 3", "Printing"

5    colKeys = objDictionary.Keys

6    Wscript.Echo "First run: "

7    For Each strKey in colKeys

8Wscript.Echo strKey

9    Next

10   objDictionary.RemoveAll

11   colKeys = objDictionary.Keys

12   Wscript.Echo VbCrLf & "Second run: "

13   For Each strKey in colKeys

14    Wscript.Echo strKey

15   Next

当脚本在 CScript 运行的时候,如下的信息显示在命令行中。和你看见的一样,第二次输出的时候是空的,因为 Dictionary 已经没有任何的 keys 了。

First run:

Printer 1

Printer 2

Printer 3

Second run:


Removing a Specific Key-Item Pair from a Dictionary

和移走所有的 key-item 对不同,你有的时候可能向移走一个单独的 key 和item。例如,假如你的脚本来从一系列的计算机上获得时间日志。脚本被设计成尝试联系每个计算机跟踪每个成功和失败。如果不能连接到计算机上,脚本尝试重新连接,知道连接到计算机并获得所有的日志信息。在这个假想的情况下,可能你的

Dictionary 中有如下的 keys:

atl-dc-01

atl-dc-02

atl-dc-03

atl-dc-04

atl-dc-05

当脚本运行的时候,它可能不能连接到计算机

atl-dc-03,atl-dc-04,在这种情况下,脚本去尝试重新连接这些计算机。但是脚本怎么知道哪个计算机需要连接,哪个不需要那?

一个解决的办法就是简单的移走已经成功连接的计算机。在第一段脚本被编译结束之后,那这个Dictionary 中只是包含如下的元素:

atl-dc-03

atl-dc-04

一旦一个计算机连接成功,就从 Dictionary 中移走这个元素,这样,如果 Dictionary 中不再含有任何元素的时候,那么所有的计算机就都连接成功了,脚本运行结束了。

为了移走单个的元素,用 Remove 方法,输入 key 的名字作为唯一的参数。例如如下的脚本语句移走了 key 为 atl-dc-02 的 key 和它对应的item。

objDictionary.Remove("atl-dc-02")

在 4.51 中的脚本创建一个有三个元素的 Dictionary 对象,回显所有的 keys。然后移走 key为 printer 2 的 key 和它的item,然后再次回显 Dictionary 的 keys:

Listing 4.51 Removing a Specified Key-Item Pair from a Dictionary

1    Set objDictionary = CreateObject("Scripting.Dictionary")

2    objDictionary.Add "Printer 1", "Printing"

3    objDictionary.Add "Printer 2", "Offline"

4    objDictionary.Add "Printer 3", "Printing"

5    colKeys = objDictionary.Keys

6    Wscript.Echo "First run: "

7    For Each strKey in colKeys

8Wscript.Echo strKey

9    Next

10   objDictionary.Remove("Printer 2")

11   colKeys = objDictionary.Keys

12   Wscript.Echo VbCrLf & "Second run: "

13   For Each strKey in colKeys

14    Wscript.Echo strKey

15   Next

当脚本在 CScript 运行的时候,在命令行中显示如下:

First run:

Printer 1

Printer 2

Printer 3

Second run:

Printer 1

Printer 3

在第二段脚本编译的末尾,printer 2 已经不再存在于 Dictionary 中了。

你可能感兴趣的:(设计模式,apple,配置管理,脚本)