第9章文件.docx
- 文档编号:12391384
- 上传时间:2023-04-18
- 格式:DOCX
- 页数:32
- 大小:174.33KB
第9章文件.docx
《第9章文件.docx》由会员分享,可在线阅读,更多相关《第9章文件.docx(32页珍藏版)》请在冰豆网上搜索。
第9章文件
第九章文件
文件是永久存储在外部介质上一组数据的集合。
很多程序都需要读写磁盘文件,这就涉及到如何建立文件,如何从文件中读数据,如何向文件写数据等问题。
从VisualBasic的第一个版本直到今天,文件处理都是通过使用Open语句以及其他一些相关的语句和函数来实现的。
本章讨论与文件操作相关的内容。
9.1文件类型
在VB中根据文件的结构和访问方式,可以将文件分为三类:
顺序存取文件、随机存取文件以及二进制存取文件。
9.1.1顺序存取文件
顺序存取文件又简称为顺序文件,是一种普通的正文文件。
它的存储方式是顺序存储,即一个数据接着一个数据地按序排列。
顺序文件存储格式如图9-1所示。
图9-1顺序文件存储格式
记录是构成文件的基本组成单位,它由若干个相互关联的数据项组成。
在数据处理过程中,表示一件事或某个对象的相关属性就可构成一个记录。
例如,对职工信息统计时,每个职工的信息就为一个记录,它由姓名、性别、出生年月、政治面貌、职务以及工龄等数据项组成,如图9-2所示。
姓名
性别
出生年月
政治面貌
职务
工龄
图9-2记录格式
通常记录与记录之间的分界字符为回车符,记录中字段与字段之间的分界字符为逗号。
这种存储方式只提供了第一个记录的位置,其他记录的位置则无法获得。
在顺序文件中查找某个记录必须从文件头开始找起,逐个比较,直到找到目标为止。
若要修改某个记录,则需要将整个文件读到内存中,修改后再将整个文件写回磁盘,因此很不灵活。
但由于顺序文件是按行存储,所以对于需要处理文本文件的应用程序来说,顺序文件是非常理想的。
顺序文件的优点是操作简单,占用的磁盘空间较少,缺点是无法任意取出某一个记录进行修改,而必须将全部数据读入到内存中,修改操作才可以进行。
当文件数据量很大时或只想修改一条记录时,顺序文件显得非常不方便。
9.1.2随机存取文件
以随机存取方式存取的文件称为随机文件。
随机文件很像一个数据库,它由大小相同的记录组成,每个记录又由字段组成,字段中存放着数据。
其存储结构如图9-3所示。
图9-3随机文件存储格式
每个记录前都有记录号表示该记录的开始。
在读取文件时,只要给出记录号就可迅速查找到该记录并将该记录读出;如果对该记录进行了修改,需要写到文件中时,也只要指出记录号,修改后的记录将自动覆盖原有记录。
所以,随机文件的访问速度较快,读、写、修改等操作灵活方便,但由于在每个记录前增加了记录号,从而使其占用的存储空间增大。
9.1.3二进制存取文件
二进制文件中的数据均以二进制方式存储,存储单位是字节(随机文件是按记录存取,顺序文件是按行存取)。
在二进制文件中,能够存取任意所需要的字节,可以把文件指针移到文件的任何地方。
如果将二进制文件中的每个字节看作是一条记录的话,则二进制存取模式就成了随机存取模式。
二进制存取文件的优点是存储密集、空间利用效率高,存取方式最为灵活,缺点是操作起来比较困难,工作量也较大。
9.2顺序存取文件
由于顺序文件按行存储,通常它是一个文本文件,数字和字符均以ASCII码的形式存储。
下面讨论顺序文件的操作语句。
9.2.1文件的打开
在对文件进行任何操作之前,都必须首先打开文件,同时要通知操作系统对文件进行读操作还是写操作,将数据存到什么地方。
当对文件进行读写操作时,VB会在内存中开辟一个“文件缓冲区”。
从文件中读取数据到内存以及从内存向文件写入数据都必须通过缓冲区,每个缓冲区都有一个缓冲区号,即后面所提到的文件号。
打开文件用Open语句,其语法格式如下:
Open文件名[For模式][Access访问方式][Lock类型]As[#]文件号[Len=记录长度]
例如,如果要打开D:
\VB目录下一个文件名为EXAMPLE的文件,并写入数据,指定文件号为#255,则打开文件的命令为Open"d:
\vb\EXAMPLE"ForOutputAS#255
下面我们详细介绍Open命令中各个子句的含义。
(1)文件名是指要打开的文件,可包含驱动器名及路径名。
文件名必须用双引号括起来。
例如"D:
\VB\EXAMPLE",说明要打开的文件是D盘VB目录下的EXAMPLE文件。
(2)For子句中的模式是用于描述文件打开的方式。
对顺序文件而言,有三种模式:
·Output(输出):
相当于写文件。
·Input(输入):
相当于读文件。
·Append(添加):
相当于将数据添加在文件尾部。
(3)Access子句中的访问方式是用来指定文件的存取权限,有三种方式:
·Read:
只读方式
·Write:
只写方式
·ReadWrite:
读写方式,只适用于顺序文件的Append模式。
(4)Lock子句中的类型是用于设置文件打开后的读写操作特性,有四种方式:
·Shared:
可对该文件读写。
·LockRead:
不允许读该文件。
·LockWrite:
不允许写该文件。
·LockReadWrite:
不允许读写该文件。
(5)#文件号子句中的文件号即文件缓冲区号,它必须是1到511之间的整数。
当打开一个文件并为它指定一个文件号后,该文件号就可以代表该文件,直到该文件被关闭后,该文件号才可以再别其他文件使用。
在使用文件号时,往往利用FreeFile函数获得可利用的文件号。
例如:
FileNum=FreeFile()'获得空余文件号
Open"test.txt"ForOutputAsFileNum
(6)在Len子句中,记录长度是一个小于32767的整数。
对于顺序文件来说,它是指缓冲区分配的字符个数;对随机文件来说,它是文件中记录的长度,缺省值为128。
9.2.2向文件中写数据
要建立一个顺序文件或打开一个顺序文件,并且向文件中写入数据,应该在Open语句中使用Output模式,然后用输出命令写入数据。
当处于Output模式时,就是建立文件。
如果文件已经存在,则删除该文件中的所有数据,新建一个空的文件。
如果在打开文件的过程中,想保留原文件的数据,则应该采用Append模式打开相应的文件。
在Append模式下,输出命令会将新的数据追加到该文件的尾部。
写文件的输出命令有Print语句和Write语句。
1、Print语句
Print语句的语法格式如下:
Print#文件号,[Spc(n)|Tab(n)][表达式列表][;|,]
其中:
文件号是Open语句打开文件时的文件号。
输出列表表示要写入到文件中的数据。
Spc(n)函数:
输出时插入n个空格(从当前打印位置起空出n个空格),该函数允许重复使用。
Tab(n)函数:
输出表达式时定位于第n列(从对象界面最左端第1列开始计算的第n列),该函数允许重复使用。
表达式列表:
要输出的数值或字符串表达式。
若省略,则输出一个空行,多个表达式之间可以用空格、逗号、分号分割,也可出现Spc和Tab函数。
;(分号):
表示下一字符紧随其前面字符打印。
,(逗号):
表示下一字符在下一个打印区开始打印。
注意:
如果没有“,”或“;”则输出后换行
输出列表格式较复杂,形式较灵活,在使用中必须加以注意,下面我们详细介绍Print语句的使用。
【例9.1】打开EXAMPLE文件,将字符串"WelcometoChina"写入文件中。
FileNum=FreeFile()
Open"EXAMPLE"ForOutputAsFileNum
Print#FileNum,"WelcometoChina"'将字符串写入EXAMPLE文件
Close'关闭所有打开文件
【例9.2】再次打开EXAMPLE文件,将字符串"WelcometoJiangXi"追加写入文件中。
FileNum=FreeFile()
Open"EXAMPLE"ForAppendAsFileNum''注意必须使用Append模式
Print#FileNum,"WelcometoJiangXi"'将字符串追加写入了文件
Close'关闭所有打开文件
【例9.3】打开TEST文件,从输出10个空格,再输出字符串"JingGangShan"到文件中。
FileNum=FreeFile()
Open"TEST"ForOutputAsFileNum
Print#FileNum,Spc(10);"JingGangShan"'注意Spc(10)后必须采用“;”
Close
在实际应用中,经常要将一个文本框的内容以文件的形式保存到磁盘中,通常有两种方法加以实现。
【例9.4】将整个文本框(Text1)内容一次性地写入BC1.DAT文件。
FileNum=FreeFile()
Open"BC1.DAT"ForOutputAsFileNum
Print#FileNum,Text1.Text'给出文本框名称
CloseFileNum
【例9.5】将整个文本框(Text1)内容一个字符一个字符写入BC1.DAT文件。
FileNum=FreeFile()
Open"BC1.DAT"ForOutputAsFileNum
Fori=1ToLen(Text1.text)
Print#FileNum,Mid(Text1.Text,i,1)
Nexti
CloseFileNum
2、Write语句
Write语句的语法格式如下:
Write#文件号,[输出列表]
其中,输出列表一般是指用“,”分隔的数值或字符串表达式。
Write语句的功能基本上与Print语句相同,区别在于Write语句的输出是以紧凑格式存放,即在数据项之间插入“,”,并给字符串加上双引号。
例如下列语句:
Write#1,"WELCOME","HELLO",6
上面语句就是把字符“WELCOME”、“HELLO”和数据6以紧凑格式写入文件中。
9.2.3从文件中读取数据
要读取顺序文件中的内容,应该以Input模式打开该文件,然后从中读取数据。
其格式如下三种:
格式1Input#文件号,变量列表
格式2LineInput#文件号,字符串变量
格式3Input$(读取数据,#文件号)
格式一读出的数据分别放在给出的变量中。
因此,要求变量的顺序应与文件中各个字段顺序相同,即每个变量应与其对应的字段的数据类型一致。
格式二每次从文件中读取一行信息,它不以逗号作为分界符,而以回车作为分界符。
因此,处理文本文件最为合适。
格式三给出读取的字数,故不受分界符的限制,用户可以随意从文件中读取若干数据。
【例9.6】以输入方式打开文件MY.TXT,并把该文件的全部内容读到文本框TEXT1.TEXT中。
程序如下:
Open"MY.TXT"ForInputAs#1
TEXT1.TEXT=Input$(LOF
(1),1)
CLOSE#1
9.2.4关闭文件
对文件操作操作完毕后,必须关闭文件,其语法格式如下:
Close[#文件号1],[#文件号2]…………..
若Close语句中省略了文件号,则关闭所有已经被打开的文件。
9.2.5其他相关函数
此外,无论哪种文件类型(顺序、随机、二进制)经常要用到下列函数:
1、LOF()函数
以字节方式返回被打开文件大小。
其语法格式如下:
LOF(文件号)
例如LOF
(1)返回#1文件的长度
2、LOC()函数
返回被打开文件的当前位置。
其语法格式如下:
LOC(文件号)
对于顺序位置的计算以128字节为单位,返回当前位置是第几个128字节;对于随机文件,它返回当前读写的记录号;对于二进制文件,返回当前的字节位置。
3、EOF()函数
返回值指出读文件过程中是否到了文件末端。
其语法格式如下:
EOF(文件号)
对于顺序文件,读写操作不能同时进行。
每进行一次读或写操作,都必须重新打开文件,读或写完之后再关闭文件。
9.2.6应用举例
【例9.7】建立2个具有3名大学教师三项内容(姓名、职称、年龄)的文本文件,分别命名为wenben1.txt和wenben2.txt,设计一个窗体,利用Print语句将每个教师的内容写入wenben1.txt文件,利用Write语句将相同的内容写入wenben2.txt文件,然后将2个文本进行显示,说明Print语句和Write语句的区别。
解:
为了区分Print语句和Write语句,我们用这两个语句同时打开一个内容相同的文本,并且查看最终结果,就可以对Print语句和Write语句加以区分。
操作过程如下:
(1)首先启动VB,新建一个工程,在Form1窗口中设置2个文本框(其中MultiLine属性必须设置为True)、2个命令按纽、以及2个标签。
如图9-4所示。
图9-4设计界面
(2)在该窗体上设计如下事件过程:
PrivateSubCommand1_Click()
Dimname$,fun$,age%
Open"wenben1.txt"ForOutputAs#1
Open"wenben2.txt"ForOutputAs#2
Fori=1To3
name=InputBox("输入姓名")
fun=InputBox("输入职称")
age=InputBox("输入年龄")
Print#1,name,fun,age
Write#2,name,fun,age
Nexti
Close#1,#2
EndSub
PrivateSubCommand2_Click()
Dims
Open"wenben1.txt"ForInputAs#11
Open"wenben2.txt"ForInputAs#22
Text1.Text=""
Text2.Text=""
DoWhileNotEOF(11)
LineInput#11,st
Text1.Text=Text1.Text&st&vbCrLf
Loop
DoWhileNotEOF(22)
LineInput#22,st
Text2.Text=Text2.Text&st&vbCrLf
Loop
Close
EndSub
(3)运行该程序,单击“输入”命令按纽,会出现输入对话框。
如图9-5所示。
图9-5输入对话框
(4)将3位老师的全部数据输入后,再单击“输出”命令按纽,运行结果如图9-6所示。
图9-6Print语句和Write语句输出结果效果图
由图9-6可知,Write语句输出时会在数据项之间自动插入“,”,并给字符串自动加上双引号,以区分数据和字符串;而Print语句则无。
【例9.8】设计一个窗体,说明顺序文件的存储及显示的实现过程。
解:
操作过程如下:
(1)建立一个工程,添加一个窗体Form1,在该窗体中放置一个文本框TXT(其中MultiLine属性设置为True)和两个命令按纽,分别命名为文件存储和显示文件。
(2)在该窗体上设计如下事件过程:
PrivateSubCOMMAND1_Click()'实现保存文件功能
fileno=FreeFile
Open"FILE.DAT"ForOutputAsfileno
Print#fileno,txt.Text
Close#fileno
EndSub
PrivateSubCommand2_Click()
‘实现显示文件功能
txt.Text=""
fileno=FreeFile
Open"file.dat"ForInputAs#fileno
DoUntilEOF(fileno)
LineInput#fileno,newline
txt.Text=txt.Text&newline&Chr(13)+Chr(10)
Loop
Close#fileno
EndSub
(3)启动本工程,出现Form1窗体,在文本框中输入一段文字,然后单击“存储文件”命令按纽,将文字保存到FILE.DAT文件中。
重新启动本工程,当文本框为空白时,单击“显示文件”命令按纽,则重新显示保存到FILE.DAT文件中的内容。
如图9-7所示。
图9-7运行界面
9.3随机存取文件
对随机文件的操作实际上是对文件中的记录进行操作,每个记录都有记录号并且记录长度全部相同。
那么无论是从内存向磁盘写数据,还是从磁盘读数据,都需要事先定义内存空间。
而内存空间的分配是靠变量说明来进行的,所以不管是读操作还是写操作都必须事先在程序中定义变量,变量要定义成随机文件中的一条记录的类型,一条记录又是由多个数据项组成的,每个数据项有不同的类型和长度。
因此,在程序的变量说明部分采用用户自定义类型说明语句,首先定义记录的类型结构,然后再将变量说明成该类型,这样就为这个变量申请了内存空间,用于存放随机文件中的记录。
9.3.1建立文件
首先要以随机模式打开文件,其语法格式如下:
Open文件名ForRandomAs#文件号[Len=记录长度]
随机文件的读、写都以这一模式打开,一经打开即可同时进行读、写操作。
也就是说对随机文件进行某种操作后不必关闭该文件就可进行另一种操作。
另外,在Open语句中要给出记录的长度,如果不给出则默认为128个字节。
注意:
记录长度是一条记录实际所占字节数,可以用Len函数获得。
如定义如下记录:
TypeRecord
NameAsString*8
AgeAsInteger
EndType
然后可用Len(Record)返回记录的字符数,再在Test.dat文件中写记录,就可用下面语句打开:
Open"Test.dat"ForRandomAs#1Len=Len(Record)
9.3.2关闭文件
随机文件的关闭同顺序文件一样,其语法格式如下:
Close[#文件号1],[#文件号2]…………..
若Close语句后无文件号,则关闭所有打开的文件。
9.3.3写数据
向随机文件中写入数据必须使用Put语句,其语法格式如下:
Put[#]文件号,[记录号],记录变量
其中,“#”和“记录号”是可选的。
该语句是将一个记录变量的内容写入所打开的磁盘文件中指定的记录位置处。
记录号是大于1的整数,表示写入的是第几条记录;若不指定记录号,则表示将变量内容写入下一记录位置。
例如,Pur#1,student语句表示将student变量的内容写入文件号为#1的下一记录中。
9.3.4读数据
从随机文件汇总读取数据必须使用Get语句,其语法格式如下:
Get[#]文件号,[记录号],记录变量
其中,记录变量的数据类型必须同文件中记录的数据类型一致。
该语句是从磁盘文件中将一条由记录号指定的记录内容读入到记录变量中。
记录号是大于1的整数,表示对第几条记录进行操作。
若忽略记录号,则表示读出当前记录号的后面一条记录。
例如,Get#1,2,student语句表示将1号文件中第二个记录读到student变量中。
9.3.5添加记录
要向随机访问打开的文件的末端添加新记录,应使用Put语句。
把记录号变量的值设置为比文件中的记录数多1。
例如,要在一个包含5个记录的文件中添加一个新的记录,必须将Position设置为6。
例如,下面语句可以将一个记录添加到文件的末尾:
LastRecord=LastRecord+1
Put#1,LastRecord,student
9.3.6删除记录
删除记录的方法是将被删除记录后面的记录位置向前移动,将被删记录进行覆盖,并将总记录数减1。
通过清除其字段可以删除一个记录,但是该记录仍在文件中存在。
通常文件中不能有空记录,因为会浪费空间且会干扰顺序操作。
最好将余下的记录拷贝到一个新的文件中,然后删除老文件。
例如,设recordnum为文件中记录个数变量,要删除记录号为N的某个记录,可用如下语句:
i=N
DoWhilei<=recordnum
Get#1,i+1,recvar
Put#1,i,recvar
I=i+1
Loop
'将最后一个记录清空
Recordnum=Recordnum-1
Endsub
9.3.7清除随机文件中的记录
清除随机文件中的记录操作步骤如下:
(1)创建一个新的文件。
(2)把所有有用的记录从原文件复制到新文件。
(3)关闭原文件并用Kill语句删除。
(4)使用Name语句以原文件的名字重新命名新文件。
9.3.8应用举例
【例9.9】随机文件操作示例。
解:
例题中,要用到控件数组的建立,请详见第四章。
在应用程序编写过程中,可能用到一些类型相同且功能相近的控件,这时可以将这些控件定义为控件数组
下面我们以学生记录为例,说明随机文件的各种操作方法。
(1)新建一个工程,在窗体Form1中添加4个标签、4个文本框(采用TEXT1控件数组)和4个命令按纽(“插入记录”、“删除记录”、“显示记录”三个命令按纽采用Command1控件数组,“退出”命令按纽采用Command2),设计界面如图9-8所示。
图9-8设计界面
(2)在该窗体中设计如下事件过程:
PrivateTypestudtype'定义随机文件结构
noAsString*4
nameAsString*10
ageAsInteger
classAsString*5
EndType
DimstudAsstudtype'申明变量
DimrecnumAsInteger
PrivateSubForm_Load()'初始化界面
Fori=0To3
Text1(i)=""
Next
EndSub
PrivateSubCommand1_Click(IndexAsInteger)‘插入、删除、显示功能的实现
OnErrorResumeNext
recnum=InputBox("输入记录号","数据输入")
Ifrecnum=0ThenExitSub
Open"stud.dat"ForRandomAs#1Len=Len(stud)
IfIndex=0Then
totalrec=LOF
(1)/Len(stud)
Fori=totalrecTorecnumStep-1
Get#1,i,stud
Put#1,i+1,stud
Next
stud.no=Text1(0).Text
stud.name=Text1
(1).Text
stud.age=Text1
(2).Text
stud.class=Text1(3).Text
Put#1,recnum,stud
EndIf
IfIndex=1Then
totalrec=LOF
(1)/Len(stud)
Fori=recnumTototalrec-1
Get#1,i+1,stud
Put#1,i,stud
Next
stud.no=""
stud.name=""
stud.age=""
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第9章 文件
![提示](https://static.bdocx.com/images/bang_tan.gif)