Office VBA开发经典:中级进阶卷
上QQ阅读APP看书,第一时间看更新

1.2 二进制方式读写文件

计算机中的文件都是以二进制方式存储的,文本文件可以用文本编辑软件查看和编辑,本质上也是以字节为单位存储在磁盘上。

因此,学习用二进制方式读写文件,有助于理解文件和字符串的关系。同时以字节数组这种数据类型为媒介,可以方便地对文本文件进行拆分和合并。

1.2.1 字符串与字节数组的互换

在VBA中,String和Byte类型的数组可以通过StrConv函数互相转换,当字符串中的每个字符是英文字母或半角字符时,一个字符占据1个字节(Byte);当出现中文汉字或全角字符时,一个字符会拆分为两部分,也就是占据2个字节。

下面的代码把字符串“VBA学习”转换为字节数组,并在立即窗口打印字节数组的信息,最后再把字节数组转换为字符串。

代码分析:“VBA学习”共5个字符,但由于后2个是汉字,所以转换为字节数组后,数组长度为7,分别从b(0)到b(6),如图1-16所示。

图1-16 字符串与字节数组的关系

在运行上述代码过程中,通过本地窗口可以看到字节数组b的构成,如图1-17所示。

图1-17 字节数组的构成

上述过程运行完毕后,在立即窗口打印出字节数组的长度以及每个元素的值,并且把字节数组恢复为字符串,如图1-18所示。

图1-18 运行结果

1.2.2 文本文件的写入

二进制方式打开文件的语句是:

    Open Path For Binary Access Write As #1

使用Put语句向文件中写入内容。Put语句的语法格式为:

    Put #1,Pos,data

其中,#1是文件号,Pos用于指定文件的写入位置,如果不指定该参数,则默认在文件结尾处写入。data是要写入的内容,可以是字符串或变量,也可以是字节数组。

下面的程序演示了二进制方式向文件中先后写入两个字符串。

上述代码执行后,记事本中的内容为“VBA程序设计”,查看该文件的属性,可以看到文件大小为11字节。因为“程序设计”4个汉字占据8字节,如图1-19所示。

图1-19 文件的大小

1.2.3 文本文件的读出

二进制方式读取文件的语句是:

    Open Path For Binary Access Read As #1

使用Get语句从文件中读入内容。Get语句的语法格式为:

    Get #1,Pos,Byte()

其中,Pos参数用来指定读取位置,如果不指定,则从上次读取完毕的位置开始读。

Byte()是用来存放读出的数据的字节数组。

在读取的过程中,有两点需要注意:一是使用Get读取过程中,读取位置也随之向后移动;二是声明的字节数组的大小决定读出内容的多少。

假设一个文本文件中的内容是“VBA程序设计”,共7个字符11个字节。下面的过程分两次读取其中的内容。

代码分析:上述代码中预先指定了字节数组b1可以存放5个字节,b2可以存放6个字节。因此,当执行Get #1, , b1这句时,b1将获取文件中的前5个字节,也就是“VBA程”,b2接着获取其后的剩余部分。

运行上述代码,立即窗口打印出字符串s1和s2,如图1-20所示。

以上分批次读取一个文件的原理,是实现拆分文件的理论基础。

在实际编程过程中,经常把文件的所有内容读取到一个字符串变量中,因此改写为如下过程。

图1-20 字节数组转换为字符串

代码分析:要把文件所有内容获取到字节数组中,需要事先知道文件的长度,也就是文件的字节数,可以用FileLen直接获取文件长度,也可以打开文件后用LOF函数获取。知道了文件的长度,就可重新定义数组的上下界。

运行上述代码,立即窗口将打印出文件中的所有内容。

1.2.4 文本文件的拆分

如果文本文件中的内容很多,不方便操作时,就需要拆分为若干个小文件,具体拆分为多少个小文件、从什么位置开始拆分,这些基准可以根据实际情况而定。

假设“静夜思.txt”文本文件里面存放的内容如图1-21所示。

图1-21 文件内容

可以看到,里面每一句都是5个汉字再加1个中文标点,也就是说每句占据12个字节,整个文件48字节。现在要求把这个文件拆分为4份,每个小文件保存一句,命名为Part#.txt。

代码分析:由于每句占据12字节,所以字节数组要规定为b(0 To 11) As Byte,使得每次恰好读出12字节。

然后在循环体中依次读取每一行,并且把每次产生的字节数组保存到不同的子文件中。

上述过程运行后,可以看到文件夹中多了4个子文件,如图1-22所示。

图1-22 文件的拆分结果

1.2.5 文本文件的合并

平时可能会遇到将很多格式比较相似的记事本文件汇总到同一个文件中的情况。文件合并过程与拆分过程恰好相反,不同的是文件合并过程中,要多次读取每个子文件,然后写入总文件中。

下面的实例在打开总体文件的前提下依次打开每个子文件,读取内容到数组,然后立即写入总文件。

代码分析:总文件的文件号是#1,子文件的文件号是#2。

运行上述代码,计算机中产生一个名为Merged.txt的新文件,该文件内容是一首完整的“静夜思”。

1.2.6 二进制文件的复制

除了处理文本文件外,还可以使用二进制方式读写计算机中的各种类型的文件,假设读取文件X到字节数组B中,再把字节数组B写入文件Y中,这样就实现了文件的复制。

下面的过程把PythonLogo.png这个图片读出到数组,然后把数组写入New.png。

运行上述过程后,将在磁盘中多了一个New.png图片,这个图片文件与原始图片文件完全相同。

上述代码的源文件为“实例文档01b.xlsm”。