![]() ![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
VB考试教程:文件处理之四文件系统 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
作者:佚名 文章来源:不详 点击数 更新时间:2008/4/18 14:46:18 文章录入:杜斌 责任编辑:杜斌 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
在计算机科学技术中,常用“文件”这一术语来表示输入输出操作的对象。所谓“文件”,是指记录在外部介质上的集合。例如用Word或Excel编辑制作的文档或表格就是一个文件,把它存放在磁盘上就是一个磁盘文件,输出到打印机上就是一个打印机文件。 文件通常存放在磁盘上,通过“路径”指明它在磁盘上的位置。“路径”是由目录(也称文件夹)和文件名组成。 1、文件说明与文件结构 文件是信息的集合,每个文件都有一个区别于其它文件的名字。下面先介绍如何对数据文件命名,然后再介绍VB中文件的一般结构和种类。 (1)文件说明 所谓文件说明,指的是文件的命名规则。在VB中,文件说明的一般格式为: 设备名:文件引用名 例如:A:myfile.abc 这里的“A:”是设备名,而“myfile.abc”是文件引用名。 设备名是存放文件设备的名称,如磁盘、磁带、打印机等。在微机中,存放文件的主要设备是磁盘,其名称通常为A:,B:,C:,D:等,分别A,B,C,D驱动器。 文件引用名由两部分组成,即文件基本名和扩展名。其中文件基本名以字母开头(在DOS环境下,最多不超过8个字符,在Windows环境下,不超过255个字符);扩展名是可选的,最多不超过3个字符。 下面字符可以做文件基本名和扩展名:
完整的文件说明由设备名和文件引用名构成。对于磁盘文件,还可以含有路径。例如: c:\textfile\sprot.tex 另外,文件说明不区分大小写。 (2)文件结构和分类
为了有效地存取数据,数据必须以某种特定的方式存放,这种特定的方式称为文件结构。 VB的文件由记录组成,记录由字段组成,字段又由字符组成。 字符:是构成文件的最基本单位。字符可以是数字、字母、特殊符号或单一字节。这里说的字符一般为西文字符,一个西文字符用一个字节存放。如果为汉字字符包括汉字和全角字符,则通常由两个字节存放。也就是说一个汉字字符相当于两个西文字符。一般把用一个字节存放的西文字符称为“半角”字符,而把汉字和用两个字符存放的字符称为“全角”字符。但VB支持双字节字符,在计算字符串长度时,一个西文字符和一个汉字都作为一个字符计算,只是它们所占的内存空间不一样。例如“VB程序设计”的长度为6,而所占的字节数为10。 字段:也称域。字段由若干个字符组成,用来表示一项数据。例如邮政编码“100859”就是由6个字符组成的一个字段。而姓名“张三”也是一个字段,由2个汉字组成。 记录:由一组相关的字段组成。例如在通信录中,每个人的姓名、单位、地址、电话号码、邮政编码等构成一个记录。在VB中,以记录为单位处理数据。 文件:文件由记录构成,一个文件含有一个以上记录。
在计算机中,文件随着分类标准的不同可分为不同的类型。 按照文件的存取方式及其组成结构来分可以分为两种类型:顺序文件、随机文件; 顺序文件:结构较简单,文件中的记录一个接一个地存放。在这种文件中,只知道第一个记录的存放位置,其它记录的位置无从知道。当要查找某个数据时,只能从文件头开始,一个记录一个记录地顺序读取,直到找到为止。这种类型的文件组织比较简单,占空间少,容易使用,但维护困难,适用于有一定规律且不经常修改的数据。 随机文件:又称直接存取文件,简称随机文件或直接文件。随机文件的每个记录都有一个记录号,在写入数据时只要指定记录号,就可以把数据直接存入指定位置。而在读取数据时,只要给出记录号,就可直接读取。在记录文件中,可以同时进行读、写操作,所以能快速地查找和修改每个记录,不必为修改某个记录而像顺序文件那样,对整个文件进行读、写操作。其优点是数据存取较为灵活、方便,速度快,容易修改,主要缺点是占空间较大,数据组织复杂。 按照文件的数据编码方式来分可以分为ASCII码文件和二进制文件; ASCII码文件:又称文本文件。它以ASCII方式保存文件,可用字处理软件建立和修改(必须以纯文本文件保存)。 二进制文件:不能用普通的字处理软件编辑,占空间较小。 按照文件的特征属性来分可以分为系统文件、隐藏文件、只读文件、普通文件和存档文件; 按照文件的数据性质来分可以分为程序文件和数据文件。 程序文件:这种文件存放的是可以由计算机执行的程序,包括源文件和可执行文件。在VB中,扩展名为.exe,.frm,.vbp,.vbg,.bas,.cls等的文件都是程序文件。 数据文件:数据文件用来存放普通的数据,例如学生的考试成绩、职工工资、商品库存等。这类数据必须通过程序来存取和管理。 2、文件的打开与关闭 在VB中,数据文件的操作按下述步骤进行:
一个文件必须先打开或建立后才能使用。如果一个文件已存在,则打开该文件;如果不存在,则建立该文件。
在打开(或建立)的文件上执行所要求的输入输出操作。在文件处理中,把内存中的数据传输到相关联的外部设备(如磁盘)并作为文件存放的操作叫做 写数据,而把数据文件中的数据传输到内存程序中的操作叫做读数据。一般来说,在主存与外设的数据传输中,由主存到外设叫做输出或写;而由外设到主存叫做输入或读。
文件处理一般需要以上三步。在VB中,数据文件的操作通过有关的语句和函数来实现。 下表列出了三种直接文件访问类型的各种文件访问的所有语句和函数。
顺序的访问是为普通的文本文件的使用而设计的。文件中每一个字符都被假设为代表一个文本字符或者文本格式序列,比如换行符(NL)。数据被存储为ASCII字符。 而为随机型访问打开的文件则认为是由相同长度的记录集合组成。可用记录类型来创建由各种各样的字段组成的记录,每个字段可以有不同的数据类型。数据作为二进制信息存储。 二进制访问允许使用文件来存储所希望的数据。除了没有数据类型或者记录长度的含义外,它与随机访问很相似。 3、顺序文件 所谓的顺序文件,通常指的是普通的文本文件,文件中的字符包括文本字符及控制字符如",","chr(14)","cr,lf" ,"chr(10)等。 由于这类型文件的信息是按照顺序从头到尾按顺序排列,而且只提供第一条记录的存储位置,所以对其中的数据信息进行处理是相当困难的。 (1)顺序文件的打开 VB中用Open语句打开或建立一个文件。 打开顺序文件的语法结构如下: Open 文件说明 [For 方式] [Access 存取类型] [lock] As [#] 文件号 [Len=记录长度] Open语句的功能是:为文件的输入输出分配缓冲区,并确定缓冲区所使用的存取方式。 Open语句的语法参数及其说明:
方式是可选的,如果省略,则为随机存取方式,即Random方式。
如果不使用Lock子句,则默认为Lock Read Write。
在顺序文件中,“记录长度”不需要与各个记录的大小相对应,因为顺序文件各个记录的长度可以不相同。当打开顺序文件时,在把记录写入磁盘或从磁盘读出记录之前,“记录长度”指出要装入缓冲区的字符数,即确定缓冲区的大小。缓冲区越大,占用空间越大,文件的输入输出操作越快。默认时缓冲区的容量为512字节。 特别说明:
下面的示例就是利用Open语句中参数的不同设置来做到文件的输出与输入。
(2)顺序文件的文件的关闭 文件的读写操作结束后,应将文件关闭,这可以通过Close语句实现。其格式为: Close[[#]文件号][,[#]文件号]…… 说明:
(3)顺序文件的写操作 前面讲过,数据文件的写操作分三步进行,即打开文件、写入文件和关闭文件。其中打开文件和关闭文件分别由Open和Close语句来实现,写入文件由Print #或Write #语句来完成。
Print #的功能是:把数据写入文件中。它与Print方法的功能类似,只不过Print方法所“写”的对象是窗体、打印机或图片框,而Print #语句所“写”的对象是文件。 Print #语句格式: Print # 文件号,[[Spc(n)│Tab(n)][表达式表][;│,]] 例如:Print # 1,A,B,C 把变量A,B,C的值写到文件号为1的文件中。 如果是Print A,B,C 则把变量A,B,C的值“写”到窗体上。 说明: 1)“文件号”的含义同前,数据被写入该文件号所代表的文件中。 2)其它参量,包括Spc函数、Tab函数、“表达式表”及尾部的分号、逗号等与Print方法中相同。如“表达式表”也可以省略,如果省略,将向文件中写入一个空行。分号和逗号分别对应紧凑格式和标准格式。但值得说明的是,在使用分号时,如果数据是数值,由于数值数据前有符号位,后有空格,所以使用分号不会给以后读取数据造成麻烦,但是如果数据是字符串,特别是变长字符串,用分号分隔就有可能引起麻烦,因为输出的字符串数据之间没有空格。例如,设: A="Beijing",B="Shanghai",C="Tianjin" 则执行: Print # 1,A;B;C 后,写到磁盘上的信息为“BeijingShanghaiTianjin”。为了使输出的各字符串明显的分开,可以人为的插入逗号,即改为: Print # 1,A;",";B;",";C 这样写入文件的信息为:“Beijing,Shanghai,Tianjin”。 3)实际上,Print #语句的任务只是将数据送到缓冲区,而数据由缓冲区写到磁盘文件的操作是由文件系统来完成的。对于用户来说,可以理解为由Print #语句直接将数据写入磁盘文件。但是执行Print #语句后,并不是立即把缓冲区中的内容写入磁盘,只有满足下列条件之一时才写盘:
例1: Private Sub Form_Click() 这个过程的执行是:先在C盘的temp目录下打开一个名为tel.dat的输出文件(如果没有该文件,则建立一个),文件号为1,然后分别输入姓名、电话号码、地址,最后关闭。 注意:这里的“temp”文件夹要存在,如果没有,可以先在C盘下建立,当然,也可以用其它名字。可用“记事本”查看。
格式: Write # 文件号,[表达式表] 功能: 和 Print #语句一样,用Write #可以把数据写入顺序文件中。例如: Write # 1,A,B,C 将把变量A,B,C的值写入文件号为1的文件中。 说明: 1)“文件号”和“表达式表”的含义同前。当使用Write #语句时,文件必须以Output或Append方式打开。“表达式表”中的各项以逗号分开。 2)Write # 语句与Print #语句的功能基本相同,其主要区别有以下两点:
例2: Private Sub Form_Click() 可将该例与例1比较。 3)如果试图用Write #语句把数据写到一个用Lock语句限定的顺序文件中去,则会发生错误。 用Open语句建立的顺序文件是ASCII文件,可以用字处理程序来查看或修改。顺序文件由记录组成,每个记录是一个单一的文本行,它以回车换行序列结束。每个记录又被分成若干个字段,这些字段是记录中按同一顺序反复出现的数据块。在顺序文件中,每个记录可以具有不同的长度,不同记录中的字段的长度也可以不一样。 当把一个字段写入变量时,存储字段的变量的类型决定了该字段的开头和结尾。如果把字段存入字符串变量,则下列符号标示该字符串的结尾:
如果把字段写入数据变量,则下列符号标示该字段的结尾:
例3:从键盘上输入4个学生的数据,然后把它们存放到磁盘文件中。 学生的数据包括姓名、学号、年龄、住址,用一个记录类型来定义。按下述步骤编写程序: 在标准模块中定义如下记录类型: Type stu 在窗体层输入如下代码: Option Base 1 编写如下的窗体事件过程: Private Sub Form_Click() 程序运行后,从键盘上输入学生人数如4个,分别输入他们的姓名、学号、年龄、住址。
在字处理软件中查看内容为: "王大力 ",9901,19,"3号楼202室 " 可以看出,由于用Write #语句执行写操作,文件中各数据项用逗号分开,且字符串放在双引号中。 (4)顺序文件的读操作 顺序文件的读操作分三步进行,即打开文件、读数据文件和关闭文件。其中打开、关闭文件的操作如前所述,读数据的操作由Input #语句和Line Input #实现。
格式: Input # 文件号,变量表 功能: Input #语句从一个顺序文件中读出数据项,并把这些数据项赋给程序变量。例如: Input #1,A,B,C 从文件中读出3个数据项,分别把它们赋给A,B,C三个变量。 说明: 1)“文件号”的含义同前。“变量表”由一个或多个变量组成,这些变量既可以是数值变量,也可以是字符串变量或数组元素,从数据文件中读出的数据赋给这些变量。文件中的数据项的类型应与Input #语句中变量的类型匹配。 2)在用Input #语句把读出的数据赋给数值变量时,将忽略前导空格、回车或换行符,把遇到的第一个非空格、非回车和换行符作为数值的开始,遇到空格、回车或换行符则认为数值结束。对于字符串数据,同样忽略开头的空格、回车或换行符。如果需要把开头带有空格的字符串赋给变量,则必须把字符串放在双引号中。 3)Input #与InputBox函数类似,但InputBox要求从键盘上输入数据,而Input #语句要求从文件中输入数据,而且执行Input #语句时不显示对话框。 4)Input #也可用于随机文件中。 例4:把前面建立的学生数据文件(stu_list)读到内存,并在屏幕(窗体)上显示出来。 该程序标准模块不变,窗体层代码也一样,只是窗体事件过程为: Private Sub Form_Click() 运行结果为: 例5:见教材P356。利用Print #语句从一个文件中读取数据,然后把它显示在窗体上。 Private Sub Form_Click()
格式: Line Input # 文件号,字符串变量 功能: Line Input #语句从一个顺序文件中读取一个完整的行,并把它赋给一个字符串变量。 说明: 1)“文件号”的含义同前。“字符串变量”是一个字符串简单变量名,也可以是一个字符串数组元素名,用来接收从顺序文件读出的字符串。 2)在文件操作中,Line Input #是十分有用的语句,它可以读取顺序文件一行的全部内容,直至遇到回车符为止。此外,对于以ASCII码存放在磁盘上的各种语言源程序,都可以用Line Input #语句一行一行地读取。 Line Input #与Input #语句功能类似,只是Input #语句读取的是文件中的数据项,而Line Input #语句读取的是文件中的一行。
3)Line Input #语句也可用于随机文件。 Line Input #语句常用来复制文本文件,见下例: 例6:把一个磁盘文件的内容读到内存并在文本框中显示出来,然后把该文本框中的内容存入另一个磁盘文件。 首先用字处理软件(例如“记事本”)建立一个名为“Smtext1.txt”的文件(该文件存放在C盘的Temp目录下),内容如下: 经五丈原 该文件有6行,输入时,每行均以回车键结束。 在窗体上建立一个文本框,MultiLine属性设置为True,然后编写如下代码: Private Sub Form_Click() 程序说明: 上述过程首先打开一个磁盘文件smtext1.txt,用Line Input #语句把该文件的内容一行一行地读到变量aspect中,每读一行,就把该行连到变量whole,加上回车换行符。然后把变量whole的内容放到文本框中,并关闭该文件。,此时文本框将分行显示smtext1.txt的内容。之后,程序建立一个名为smtext2.txt的文件,并把文本框的内容写入该文件。所以程序运行结束后,文本框及两个磁盘文件具有相同的内容。 运行后的窗体界面为:
格式: Input(n,#文件号) 功能: Input函数返回从指定文件中读出的n个字符的字符串。也就是说,它可以从数据文件中读取指定数目的文件。例如: x=Input(100,#1) 从文件号为1的文件中读取100个字符,并把它赋给变量x。 Input函数执行所谓“二进制输入”。它把一个文件作为非格式的字符流来读取。例如,它不把回车-换行序列看作是一次输入操作的结束标志。因此,当需要用程序从文件中读取单个字符时,或者是用程序读取一个二进制的或非ASCII码文件时,使用Input函数较为适宜。 例7:编写程序,在文件中查找指定的字符串。 为了查找文件中指定的字符串,可以先打开文件,用Input(1,1)搜索要查找的字符串的首字符,再试着进行完整的匹配。更直观的做法是:把整个文件读入内存,放到一个变量中,然后从这个变量中查找所需要的字符串。在VB中,一个字符串变量最多可存放20亿个字符。 首先用字处理软件(例如“记事本”)建立一个名为“xyz.txt”的文件(该文件存放在C盘的Temp目录下),作为练习,可以随便输入。 然后在窗体中添加如下程序: Private Sub Form_Click()
2、随机文件 随机文件有以下特点: 1)随机文件的记录是定长记录,只有给出记录号n,才能通过[(n-1)×记录长度]计算出该记录与文件首记录的相对地址。因此在用Open语句打开文件时,必须指定记录的长度。 2)每个记录划分为若干个字段,每个字段的长度等于相应的变量的长度。 3)各变量(数据项)要按一定格式置入相应的字段。 4)打开随机文件后,既可读也可写。 随机文件与顺序文件的读写操作类似,但通常把需要读写的记录中的各字段放在一个记录类型中,同时应指定每个记录的长度。 (1)随机文件的写操作 随机文件的写操作分为4步: 1)定义数据类型 随机文件由固定长度的记录组成,每个记录含有若干个字段。可以把记录中的各个字段放在一个记录类型中,记录类型用用Type……End Type定义。前面已经看到Type……End Type在标准模块中使用。 2)打开随机文件 与顺序文件不同,打开一个随机文件后,既可用于写操作,又可用于读操作。打开随机文件的一般格式为: Open "文件名称" For Random As #文件号[Len=记录长度] “记录长度”等于各字段长度之和,以字符(字节)为单位。如果省略“ Len=记录长度”,则默认长度为128字节。 3)将内存中的数据写入磁盘 随机文件的写操作通过Put语句来实现。其格式为: Put #文件号,[记录号],变量 这里的“变量”是除对象变量和数组变量外的任何变量(包括含有单个数组元素的下标变量)。Put语句把“变量”的内容写入由“文件号”所指定的磁盘文件中。 说明:
Put #2,,Filebuff
4)关闭文件 关闭文件的操作与顺序文件相同。 (2)随机文件的读操作 从随机文件中读取数据的操作与写文件操作步骤类似,只是把第三步中的Put语句用Get语句来代替。其格式为: Get #文件号,[记录号],变量 Get语句把由“文件号”所指定的磁盘文件中的数据读到“变量”中。 “记录号”的取值范围同前,它是要读的记录的编号。如果省略“记录号”,则读取下一个记录,即最近执行Get或Put语句后的记录,或由最近的Seek函数指定的记录。同样,省略“记录号”后,逗号不能省略。例如: Get #1,,Filebuff Get语句的其它说明,包括“文件号”、“变量”的含义以及在读变长字符串、变体等变量时的一些规则,均与Put语句类似,不再重复。 下面通过一个例子说明随机文件的读写操作。 例8:建立一个随机存取的工资文件,然后读取文件中的记录。 为了便于说明问题,使用如下表所示的简单的文件结构。
按以下步骤操作: 1)定义数据类型 工资文件的每个记录含有4个字段,其长度(字节数)及数据类型见下表。
根据上面规定的字段长度和数据类型,定义记录类型。 在标准模块中定义如下记录类型: Type RecordType 在窗体层定义该类型的变量: Dim Recordvar As RecordType 2)打开文件,并指定记录长度 从前面可知,要建立的随机文件的每个记录的长度为10+15+2+4=31个字节,因此用下面的语句打开文件: Open "Employee.dat" For Random As #1 Len=31 用上面的语句打开文件时,记录的长度通过手工计算得到。当记录含有的字段较多时,这种手工计算很不方便,也容易出错。实际上,记录类型变量的长度就是记录的长度,可以通过Len函数求出来,即: 记录长度=Len(记录类型变量) 因此,打开文件的语句可以改为: Open "Employee.dat" For Random As #1 Len=Len(Recordvar) 注意这里的两个Len的意义是不同的,等号左边的Len是Open语句中的子句,等号右边的Len是一个函数。 3)从键盘上输入记录中的各个字段,对文件进行读写操作 打开文件后,就可以输入数据,并把数据记录写入磁盘文件。程序如下:
Recordvar.EmName = InputBox("职工姓名:") 用上面的程序段可以把一个记录写入磁盘文件Employee.dat。把这段程序放在循环中,就可以把指定数量的记录写入文件中。不必关闭文件,就可以从文件中读取记录。例如: Get #1,,Recordvar 4)关闭文件 以上是建立和读取工资文件的一般操作,在具体编写程序时,应设计好文件的结构。 下面是完整的程序。 在标准模块中定义如下记录类型: Type RecordType 在窗体层定义该记录类型变量和其它变量: Dim Recordvar As RecordType 编写如下通用过程,执行输入数据及写盘操作: Sub File_Write() 随机文件中读数据操作: 随机文件建立后,可以从文件中读取数据。从随机文件中读数据有两种方法:一种是顺序读取,一种是通过记录号读取。由于顺序读取不能直接访问任意指定的记录,因而速度较慢。 编写如下通用过程,执行顺序读文件操作: Sub File_Read1() 该过程从前面建立的随机文件Employee.dat中顺序地读出全部记录,从头到尾读取,并在窗体上显示出来。
随机文件的主要优点之一,就是可以通过记录号直接访问文件中任一个记录,从而可以大大提高存取速度。在用Put语句向文件写记录时,就把记录号赋给了该记录。在读取文件时,通过把记录号放在Get语句中可以从随机文件取回一个记录。 下面是通过记录号读取随机文件Employee.dat中任一记录的通用过程: Sub File_Read2() 该过程在Do……Loop循环中要求输入要查找的记录号。如果输入的记录号在指定的范围内,则在窗体上输出相应记录的数据;当输入的记录号为0时结束程序;如果输入的记录号不在指定的范围内,则显示相应的信息,并要求重新输入。
上述三个通用过程分别用来建立随机文件、用顺序方式或通过记录号读取文件记录。 在下面的窗体事件过程中调用这三个过程: Private Sub Form_Click() 上述程序运行后,单击窗体,在显示的输入对话框(如下图)中输入0-3(暂不输入4)之间的数字,即可调用相应的通用过程执行随机文件的读写操作。 该程序可以执行4种操作,即写文件、顺序读文件、通过记录号读文件和删除文件中指定的记录。其中删除记录的操作将在后面介绍。 (3)随机文件中记录的增加与删除 1)增加记录 在随机文件中增加记录,实际上是在文件的末尾附加记录。其方法是,先找到文件最后一个记录的记录号,然后把要增加的记录写在它的后面。 前面的通用过程File_Write具有建立文件和增加记录两种功能。也就是说,如果打开一个已经存在的文件,则写入的新记录将附加到该文件后面。 运行前面的程序,出现对话框后键入1,并单击“确定”按钮,然后再输入几个记录数据。 输入结束后,回到选择对话框,键入2并“确定”后,将在窗体上显示文件中的所有记录,可以看出新增加的记录已附在原来记录的后面。 2)删除记录 在随机文件中删除一个记录时,并不是真正删除记录,而是把下一个记录重写到要删除的记录上,其后的所有记录依次前移。例如前面建立的文件有4个记录(为便于操作,简单的输入): 张三 办公室 35 850 假定要删除第二个记录“李四 财务处 32 780”。其方法是:将第三个记录写到第二个记录上,第四个记录写到第三个记录上,其内容变为: 张三 办公室 35 850 文件中仍有4个记录,原来的第二个没有了,最后两个记录相同。也就是说,最后一个记录是多余的。为了解决这个问题,可以把原来的记录个数减1,由4个变为3个。这样,当再向文件中增加记录时,多余的记录即被覆盖。 根据上面分析,编写删除记录的通用过程如下: Sub Deleterec(position As Integer) '参数position是要删除的记录的记录号 上述过程用来删除文件中的指定的记录,参数 position是要删除的记录的记录号。该过程用后面的记录覆盖前面要删除的记录,并将其后的记录依次前移,移动完成后,最后的记录号减1。 该过程是前面程序的一部分,可以在前面的事件过程中调用。把事件过程中的“Case 4”后面的部分改为: p = InputBox("输入记录号:") 运行程序后,在选择对话框中输入4,将显示一个对话框,要求输入要删除的记录的记录号。输入2并单击“确定”按钮,第二个记录即被删除,回到选择对话框。此时如果输入2,单击“确定”按钮,即可看到第二个记录已被删除。 (4)用控件显示和修改随机文件 前面介绍了随机文件的读写及修改操作。执行这些操作的程序是用VB编写的,然而其操作方法和显示方法与传统语言没什么区别。如果能结合VB的控件来显示和修改随机文件中的数据,效果要好得多。下面通过一个例子说明它的实现方法。 例9:编写程序,用控件显示和修改随机文件中的数据。 我们仍然使用前面建立的“employee.dat”文件来设计程序。按以下步骤操作: 1)在标准模块中定义记录类型(同前)。 2)在窗体模块中定义变量(同前)。 3)在窗体上添加控件,并设置属性,如下:
其中4个文本框是一个文本框控件数组的4个元素,其控件组名是Text1,并将其Text属性设置为空白。 4)编写代码 编写通用过程: Sub display() 编写事件过程: 打开文件: Private Sub Command3_Click() 该过程用来打开文件,计算出最后一个记录的记录号,并把当前记录号设置为1,然后调用display过程显示记录的内容。 显示前一个记录: Private Sub Command1_Click() 该事件过程用来显示当前记录的前一个记录。由于第一个记录没有“前一个记录”,因此如果当前记录是第一个记录,则单击“前一记录”按钮时将显示相应的信息。 显示下一个记录: Private Sub Command2_Click() 该事件过程用来显示当前记录的下一个记录,如果当前记录是最后一个记录,则单击“下一记录”按钮时将显示相应的信息,并询问用户是否关闭文件。如果单击对话框中的“Yes”按钮,则关闭文件,结束程序运行,否则继续运行。 修改记录: Private Sub Command4_Click() 该事件过程用来修改记录。单击需要修改的字段所在的文本框,把光标移到该文本框中,就可修改该文本框的内容。修改后单击“数据修改”命令按钮,就可以把修改后的记录写入文件中,并覆盖原来的记录。 退出程序: Private Sub Command5_Click() 3、二进制文件 利用二进制存取可以获取任一文件的原始字节,即不仅能获取ASCII文件,而且能获取非ASCII文件的原始字节。这样,用户就可以读取或修改以非ASCII格式存盘的文件,例如可执行文件(.exe)
用下面的语句可以打开二进制输入/输出文件: Open 文件说明 For Binary As #文件号 为二进制存取打开的文件作为非格式化的字节序列处理。可以把记录读或写到以二进制方式打开的文件中,但文件本身不必处理成定长记录。实际上,二进制文件本身不必涉及记录,除非把文件中的每个字节看成一个记录。 通过使用二进制型访问可使磁盘空间的使用降到最小。因为二进制文件不需要固定长度的字段(在二进制文件中每个记录只占用所需字节,所以不必为字段指定长度),类型声明语句可以省略字符串长度参数。当记录中的字段需要包含大段文字时,使用二进制文件可以节省大量的磁盘空间。 (1)二进制存取与随机存取 二进制文件与随机文件的存取操作类似,这主要表现在以下两个方面: 1)不需要在读与写之间切换。在执行Open语句打开文件后,对该文件既可以读,也可以写,并且利用二进制存取可以在一个打开的文件中前后移动。 2)读写随机文件的语句也可以用于读写二进制文件,即: Get│Put #文件号,[位置],变量 在这里,“变量”可以是任何类型,包括变长字符串和记录类型;“位置”指明下一个Get或Put操作在文件的什么地方进行。二进制文件中的“位置”相对于开头而言。即第一个字节的“位置”是1,第二个字节的“位置”是2,等等。如果省略“位置”,则Get和Put操作将文件指针从第一个字节到最后一个字节顺序进行扫描。 Get语句从文件中读出的字节数等于“变量”的长度;同样Put语句向文件中写入的字节数与“变量”的长度相同。例如,如果“变量”为整型,则Get语句就把读取的2个字节赋给“变量”;如果“变量”为单精度型,则Get语句就读取4个字节。因此,如果Get和Put语句中没有指定“位置”,则文件指针每次移过一个与“变量”长度相同的距离。 二进制文件与随机文件也有不同之处,主要是:二进制存取可以移到文件中的任一字节位置上,然后根据需要读、写任意个字节;而随机存取每次只能移到一个记录的边界上,读取固定个数的字节(一个记录的长度)。 二进制文件只能通过Get语句或Input#函数读取数据,而Put则是向以二进制方式打开的文件中写入数据的唯一方法。 为了可以同时使用随机文件和二进制文件的优点,可以使用这样的组合--当字段的长度固定或者长度变化不大时,可以将这些字段存储在随机文件中,而对于长度变化很大的字段,可以保存在二进制文件中,而在随机文件的记录中设置一个字段指定它在二进制文件中的位置即可。这样,既可以利用随机文件的方便快捷,又可以大大节省许多磁盘空间。 (2)文件指针 在二进制文件中,可以把文件指针移到文件中任意位置。文件指针的定位通过Seek语句来实现。其格式为: Seek #文件号,位置 Seek语句用来设置文件中下一个读或写的位置。“文件号”的含义同前,“位置”是一个数值表达式,用来指定下一个要读写的位置,其值在1—231-1的范围内。 说明: 1)对于用Binary,Input,Output或Append方式打开的文件,“位置”是从文件开头到“位置”为止的字节数,即执行下一个操作的地址,文件第一个字节的位置为1。对于用Random方式打开的文件,“位置”是一个记录号。 2)在Get或Put语句中的记录号优先于由Seek语句确定的位置。此外,当“位置”为0或负数时,将产生出错信息“错误的记录号”。当Seek语句中的“位置”在文件尾之后时,对文件的写操作将扩展该文件。 与Seek语句配合的使用的是Seek函数。其格式为: Seek(文件号) 该函数返回文件指针的当前位置。由Seek函数返回的值在1—231-1的范围内。 对于用Binary,Input,Output或Append方式打开的文件,Seek函数返回文件中的字节位置(产生下一个操作的位置),对于用Random方式打开的文件,Seek函数返回下一个要读或写的记录号。 在访问二进制文件时,Seek函数与Loc函数给出相似的结果。所不同的是Loc函数返回的是最近一次读写过的字节的位置,而Seek函数返回的则是下一次要读或写的字节位置。 对于顺序文件,Seek语句把文件指针移到指定的字节位置上,Seek函数返回有关下次将要读写的位置信息;对于随机文件,Seek语句只能把文件指针移到一个记录的开头,而Seek函数返回的是下一个记录号。 例10:编写程序,建立一个二进制文件,然后用Seek函数返回各项数据的位置。 在窗体上添加3个命令按钮,Caption属性分别为“建立文件”、“返回位置”和“退出”,然后对3个按钮编写如下事件过程: “建立文件”事件过程: Private Sub Command1_Click() 该过程要求输入一个文件名,并把它作为二进制文件打开(该文件如不指定路径,则默认位置在VB98文件夹下,可以用记事本查看),然后向该文件中写入数据(学生姓名)。每输入完一个姓名,程序询问是否继续输入,键入“Y”继续,否则结束输入。
“返回位置”事件过程: Private Sub Command2_Click() Seek函数返回的是下一个要读出的字节位置。由于变量的长度为10个字节,因此第一次返回的字节位置为11,第二次为21,依次类推。 “退出”事件过程: Private Sub Command3_Click()
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() ![]() |