随机文件
随机存取文件又称为记录文件,由固定长度的记录顺序排列而成,每个记录可由多个数据项组成。由于它定长,所以可直接定位在任意一个记录上进行读或写,便于查询和修改。随机文件有以下特点:
(1) 随机文件的记录是定长的,只有给出记录号n才能通过“(n-1)×记录长度”计算出该记录与文件首记录的相对地址。因此,在用Open语句打开文件时必须指定记录的长度。
(2) 每个记录划分为若干个字段,每个字段的长度等于相应的变量的长度。
(3) 各变量要按一定格式置入相应的字段。打开随机文件后,既可读也可写。
例如学生的基本信息:学生姓名、学号、年龄。这三个信息可以用一个自定义类型StuInfo来定义:
Type StuInfo
name As String * 8 '学生姓名
id As String * 7 '学号
age As Integer '年龄
End Type
随机文件以记录为单位进行操作,使用随机文件分3个步骤:打开文件、读/写文件和关闭文件。本节中“记录”兼有两方面的含义,一个是记录类型,即用Type…End Type语句定义的类型;另一个是要处理的文件的记录。两者有联系,也有区别,要注意区分。
一、打开关闭随机存取文件
(一)打开文件
此处的打开文件是指打开随机文件,无论是创建新文件还是读/写已经存在的文件,都以同一Open命令打开(与顺序文件不同),具体有两点:
(1) 存取方式不同。在Open语句中,顺序文件的存取方式是Input, Output或Append用来读或写;随机文件的存取方式只有Random,打开后既可读也可写。
(2) Len的意义不同。对于顺序文件时,Len表示缓冲区字节数;对于随机文件,Len表示记录长度,其格式如下:
Open<文件名>FOR Random AS[#]<文件号>LEN=<记录长度>
其中:
(1) 它在磁盘上打开一个名叫<文件名>的随机存取文件,建立<文件名>与<文件号>的关联。规定该文件每个记录所含字节数=<记录长度>
(2) 文件打开后,文件指针指向文件头。
(3) 如果原来没有此文件,则自动创建一个新文件。
(4) 在该文件关闭以前,各种文件操作均使用<文件号>。
(5) 文件打开后,既可以读也可以写。
(二)关闭文件
与顺序文件的关闭方法相同,都使用Close语句。
二、读写随机存取文件
(一)写入数据
写入数据是将数据从内存写入随机文件,使用Put语句,其格式如下:
Put#<文件号>,[<记录号>],<变量名>
该语句把变量的内容写到由<文件号>所代表的磁盘文件中<记录号>所指定的记录处。如果省略<记录号>,则写到文件指针所指的记录处。
(二)读操作
随机文件的读操作把文件中由<记录号>所指定记录的内容读入指定的变量中。如果省略<记录号>,则把文件指针所指的记录内容读入指定的变量中。这里用到了Get语句,其格式如下:
Get#<文件号>,[<记录号>],<变量名>]
其中:
(1) 变量可以是任何类型。
(2) 记录号是1~2147483647之间的整数。
(3) 记录号可以默认,但逗号不能省。省去记录号则使用文件指针当前所指的记录。
(4) 文件指针指向最近一次Put或Get语句操作记录的下一记录或最近一次由Seek语句定位的记录,以最后一个操作为准。
(三)记录操作
随机文件又称为记录文件,常用操作有删除记录、增加记录、替换记录。例10-3实现了一个简单的学生信息管理,通过该示例将详细的展示添加、删除、修改记录的过程。程序的类型定义、初始化如下:
Private Type StuInfo
name As String * 8 '学生姓名
id As String * 7 '学号
age As Integer '年龄
End Type
Private student As StuInfo
Private endpos As Long '保存新添加记录的记录号
Private curpos As Long '保存当前的记录号
Private Sub Form_Load()
Open App.Path + "\" + "student.data" For Random As #1 Len = Len(student)
endpos = LOF(1) / Len(student) + 1 '计算新添加记录的记录号
curpos = 1
If LOF(1) / Len(student) >= 1 Then '有记录则显示第一个记录
Get #1, 1, student
txName.Text = student.name
txId.Text = student.id
txAge.Text = student.age
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
Close #1 ‘关闭随机文件
End Sub
1.删除记录。
对于随机文件,删除一条记录是依次将该记录的下一条记录前移,来覆盖需要删除的记录,后面将会出现重复的记录。为了改变记录数,消除重复的记录,需要进行以下操作:
(1) 生成一个新的随机义件。
(2) 将旧文件中的记录拷贝到新文件中,在尾部的重复记录除外。
(3) 关闭这两个文件。
(4) 用Kill语句删除旧文件,复制原文件的所有记录到新文件。
(5) 用Name语句将新文件名改成原文件名。
例10-3中,记录的删除过程如下:
Private Sub DelRecord_Click()
Open App.Path + "\" + "temp.tmp" For Random As #2 Len = Len(student)
For i = 1 To endpos – 1 '拷贝其他记录到临时文件
If i <> curpos Then
Get #1, i, student
Put #2, , student
End If
Next
endpos = endpos - 1
Close #1, #2
Kill (App.Path + "\" + "student.data") '删除原文件
Name App.Path + "\" + "temp.tmp" As App.Path + "\" + "student.data" '重命名
Open App.Path + "\" + "student.data" For Random As #1 Len = Len(student)
End Sub
2.增加记录
对于随机文件,增加记录实际上是加到文件尾,增加记录的步骤是:
(1) 找到随机文件的记录数,即最后一个记录的记录号,将记录数加1。
(2) 输入需要增加的记录。
(3) 将输入的记录用Put语句写到后面文件的后面。
(4) 如果还有记录需要增加,重复上面的步骤。
例10-3中,记录的添加过程如下:
Private Sub AddRecord_Click()
endpos = LOF(1) / Len(student) + 1
student.name = txName.Text
student.id = txId.Text
student.age = txAge.Text
Put #1, endpos, student
curpos = endpos
endpos = endpos + 1
End Sub
3.替换记录
用新的记录代替原有的记录,替换记录的步骤如下:
(1) 给出被替换的记录号。
(2) 输入新记录。
例10-3中,记录的替换过程如下:
Private Sub ModRecord_Click() ‘记录的修改
student.name = txName.Text
student.id = txId.Text
student.age = txAge.Text
Put #1, curpos, student
End Sub