第14章数据文件.docx
《第14章数据文件.docx》由会员分享,可在线阅读,更多相关《第14章数据文件.docx(23页珍藏版)》请在冰豆网上搜索。
![第14章数据文件.docx](https://file1.bdocx.com/fileroot1/2023-7/11/47f44a9c-1568-4910-8051-14953b0aa69e/47f44a9c-1568-4910-8051-14953b0aa69e1.gif)
第14章数据文件
第14章数据文件
14.1文件概述
所谓“文件”,是指记录在外部介质上的数据的集合。
例如用Word或Excel编辑制作的文档或表格就是一个文件,把它存放到磁盘上就是一个磁盘文件,输出到打印机上就是一个打印机文件。
广义地说,任何输入输出设备都是文件。
计算机以这些设备为对象进行输入输出,对这些设备统一按“文件”进行处理。
在程序设计中,使用文件可以不受内存大小的限制。
1.文件结构
为了有效地存取数据,数据必须以某种特定的方式存放,这种特定的方式称为文件结构。
VisualBasic文件由记录组成,记录由字段组成,字段由字符组成。
(1)字符(Character)是构成文件的最基本单位。
字符可以是数字、字母、特殊符号或单一字节。
注:
Len(“Abcd英文字母”) 8(但占内存为12个字节)
(2)字段(Field):
也称域。
单独的字符是没有任何意义的。
只有若干个字符维修组合在一起才有一定的意义。
字段由若干个字符组成,用来表示一项数据。
如:
“张三”、“550004”分别表示某人的姓名,某地区的邮编。
(3)记录(Record):
由一组相关的数据组成。
例如在通信录中,每个人的姓名、单位、地址、电话号码、邮政编码等构成一个记录,。
在VisualBasic中,以记录为单位
处理数据。
(4)文件(File):
文件由记录构成,一个文件含有若干条的记录。
综上所述:
一个文件是由若干条记录所组成,每条记录由几项数据项(字段、域)组成,每个数据项由若干个字符所组成。
指针:
当前操作的记录的标识。
2.文件种类
根据不同的分类标准,文件可分为不同的类型。
(1)根据数据性质,文件可分为程序文件和数据文件。
①程序文件(ProgramFile):
这种文件存放的是可以由计算机执行的程序
②数据文件(DataFile):
数据文件用来存放普通的数据。
(2)根据数据的存取方式和结构,文件可分为顺序文件和随机文件。
①顺序文件(SequentialFile):
顺序文件的结构比较简单,文件中的记录一个接一个地存放。
当要查找某个数据时,只能从文件头开始,一个记录一个记录地顺序读取,直至找到要查找的记录为止。
②随机存取文件(RandomAccessFile):
又称直接存取文件,简称随机文件或直接文件。
与顺序文件不同,在访问随机文件中的数据时,不必考虑各个记录的排列顺序或位置,可以根据需要访问文件中的任一个记录。
在随机文件中,每个记录的长度是固定的,记录中的每个字段的长度也是固定的。
此外,随机文件的每个记录都有一个记录号。
在写入数据时,只要指定记录号,就可以把数据直接存入指定位置。
而在读取数据时,只要给出记录号,就能直接读取该记录。
在随机文件中,可以同时进行读、写操作,因而能快速地查找和修改每个记录,不必为修改某个记录而对整个文件进行读、写操作。
随机文件的优点是数据的存取较为灵活、方便,速度较快,容易修改。
主要缺点是占空间较大,数据组织较复杂。
(3)根据数据的编码方式,文件可以分为ASCII文件和二进制文件。
①ASCII文件:
又称文本文件,它以ASCII方式保存文件。
这种文件可以用字处理软件建立和修改(必须按纯文本文件保存)。
②二进制文件(BinaryFile):
以二进制方式保存的文件。
二进制文件不能用普通的字处理软件编辑,占空间较小。
14.2文件的打开与关闭
在VisualBasic中,数据文件的操作按下述步骤进行:
(1)打开(或建立)文件
(2)进行读、写操作
(3)关闭文件
14.2.1文件的打开(建立)
其格式为:
Open文件名[For方式][Access存取类型][锁定〕As「#]文件号[Len=记录长度]
OPEN打开文件的命令
文件名:
所要建立或打开的文件名,文件名可以用绝对路径,文件名两边必须用“ “定界,是字符串形式。
方式:
Output:
顺序输出。
(具有建立顺序文件的功能)(可以用Printt和Write两种语句进行写操作)
Input:
顺序输入。
(读入)(可以用Input和LineInput两种语句进行读操作)
Append:
顺序输出方式,追加。
只能在文件尾加记录。
(具有建立顺序文件的功能)(可以用Input和LineInput两种语句进行读操作)
Random:
指定随机存取方式,
Binary:
指定二进制方式文件。
在这种方式下,可以用Get和Put语句对文件中任何字节位置的信息进行读写。
“方式”是可选的,如果省略,则为随机存取方式,即Random.
②存取类型:
放在关键字Access之后,用来指定访问文件的类型。
可以是下列类型
之一:
Read:
打开只读文件。
Write:
打开只写文件。
ReadWrite:
打开读写文件。
这种类型只对随机文件、二进制文件及用Append方式打开的文件有效。
③锁定:
LockShared:
任何机器上的任何进程都可以对该文件进行读写操作。
LockRead:
不允许其他进程读该文件。
LockWrite:
不允许其他进程写这个文件。
LockReadWrite:
不允许其他进程读写这个文件。
如果不使用Lock子句,则默认为LockReadWrite.
④文件号:
对于每个文件都指定一个号,1~511范围,其它输入输出语句或函数通过文件号与文件发生关系。
⑤记录长度:
对于用随机访问方式打开的文件,该值是记录长度;对于顺序文件,该值是缓冲字符数。
“记录长度”的值不能超过32767字节。
对于二进制文件,将忽略Len子句。
(2)Open语句兼有打开文件和建立文件两种功能。
在对一个数据文件进行读、写、修改或增加数据之前,必须先用Open语句打开或建立该文件。
如果为输入(Input)打开的文件不存在,则产生“文件未找到”错误;如果为输出(Output),追加(Append)或随机(Random)访问方式打开的文件不存在,则建立相应的文件;此外,在Open语句中,任何一个参量的值如果超出给定的范围,则产生“非法功能调用”错误,而且文件不能被打开。
下面是一些打开文件的例子:
Open"Price.dat"ForOutputAs#1
可建立或打开一个数据文件,使记录可以写到该文件中。
如果文件"Price.dat"己存在,该语句打开已存在的数据文件,新写入的数据将覆盖原来的数据。
Open"Price.dat"ForAppendAs#1
打开已存在的数据文件,新写入的记录追加到文件的后面,原来的数据仍在文件中。
如果给定的文件名不存在,则Append方式可以建立一个新文件。
Open"Price.dat"ForInputAs#1
打开已存在的数据文件,以便从文件中读出记录。
以上例子中打开的文件都是按顺序方式输入输出。
Open"Price.dat"ForRandomAs#1
按随机方式打开或建立一个文件,然后读出或写入定长记录。
Open"Records"ForRandomAccessReadLockWriteAs#1
需要注意的是:
文件的读入与输出。
?
?
?
?
?
?
?
14.2.2文件的关闭
文件的读写操作结束后,应将文件关闭,这可以通过Close语句来实现。
其格式为:
Close[[#]文件号][,[#]文件号]……
Close语句用来结束文件的输入输出操作。
例如,假定用下面的语句打开文件:
Open"price.dat"ForOutputAs#1
则可以用下面的语句关闭该文件:
Close#1
若关闭目前打开的所有文件,则可以用如下语句:
Close
第三节文件操作语句和函数
14.3.1文件指针:
指针:
是一个标识(隐含),指出文件要进行读、写操作的位置。
一、文件指针的定位可以通过如下语句:
SEEK#文件号,位置
作用:
1.对于用input、output、append方式打开的文件,是将指针定位到“位置”处。
“位置”从文件开头到“位置”为止的字节数,即执行下一个操作的地址,文件第一个字节的位置是1;
2.对于以Random方式打开的文件,“位置”是记录号。
3.在Get或Put语句中的记录号优先于由Seek语句确定的位置。
此外,当“位置”为0或负数时,将产生出错信息“错误的记录号”,若在文件尾之后时,对文件的写操作将扩展该文件。
4.与Seek语句配合使用的是Seek函数:
SEEK(文件号)
返回指定文件的当前指针位置。
对于用Input、Output或Append方式打开的顺序文件,Seek函数返回文件中的字节位置(产生下一个操作数的位置),而Seek语句是把文件指针移到指定的字节位置上;对于用Random方式打开的文件,Seek函数返回下一个要读或写的记录号,而Seek语句只能把文件指针移到一个记录的开头。
14.3.2 其他语句和函数:
1.FREEfile:
当前可用的文件号。
如果要使用的文件很多,就需要有很多文件号,使用FREEFILE就可得到当前可用的文件号,避免使用重复的号;特别当在通用过程中使用文件时,用这个函数可以避免使用其他Sub或Function过程正在使用的文件号。
利用这个函数可以把未使用的新闻公报号赋给一个变量,用这个变量作文件号,不必知道具体的文件是多少。
PrivateSubForm_Click()
Filename$=Input(“请输入要打开的文件名:
”)
Filenum=FreeFile
Openfilename$;”openedasfile#”;Filenum
Close#Filenum
EndSub
2.Loc函数
格式:
LOC(文件号)
返回由“文件号”所指定的文件的当前读写位置;随机文件而言,是读或写的最后一个记录的记录号,即当前读写位置的上一个记录;对于顺序文件,Loc函数返回的是从该文件被打开以来读或写的记录个数,一个记录是一个数据块。
3.LOF函数
格式:
LOF(文件号)
返回给文件分配的字节数(即文件的长度)。
在VB中,文件的基本单位是记录,每个记录默认的长度是128个字节。
因此,对于由VB建立的数据文件,LOF函数返回的将是128的倍数,不一定是实际的字节数。
对于用其它编辑软件或字处理软件建立的文件,LOF函数返回的将是实际分配的字节数,即文件的实际长度。
以下可以确定一个随机文件中记录的个数
RecordLength=60
Open“c:
\prog\Myrelatives”ForRandomAs#1
X=LOF
(1)
NumberOfRecords=x\RecordLength
3.EOF函数
格式:
EOF(文件号)
测试当前文件记录指针是否到末尾,值为TRUE或FALSE
EOF函数常用来在循环中测试是否已到文件尾,一般格式如下:
DoWhileNotEOF
(1)
‘文件读写语句
Loop
14.4顺序文件
文件操作三步:
打开→操作→关闭
14.4.1顺序文件的写操作:
1、Print语句
格式:
print#文件号,[[Spc(n)|Tab(n)][表达式表][;|,]]
将表达式表的内容写入文件,其中Spc函数、Tab函数、“表达式表”及尾部的分号、逗号等,含义与Print方法同。
PrivateSubForm_Click()
Open"d:
\123.txt"ForOutputAs#1
Fori=1To3
Name1=InputBox("inputname")
age=InputBox("inputage")
sex=InputBox("inputsex")
Print#1,Name1,age,sex
Nexti
Close#1
EndSub
1)Print#1
将向文件写入一个空行。
2)数值型数据写入时前有符号位,后有尾随空格,但字符串型如果用分号紧凑格式,则为了使各字符串分开,可人为地加入“,”,如:
Print#1,A$;”,”;B$;”,”;C$
注意:
不要试图以OUTPUT方式打开一已存在的文件,如果以该方式打开,原来文件内容被新的内容所覆盖(如果你希望是这样的除外。
)
如果要对已存在的文件再加入新的内容,方式选“APPEND”
如对上例中,将方式改变为Append、再运行。
2.Write语句
格式:
Wrtite#文件号,表达式表
除Print外,也可用WRITE写文件,其“表达式表”中的各项只能用“,”隔开。
WRITE同PRINT的区别在于:
1)WRITE写数据时,在磁盘上紧凑格式存放,自动以“,”为分隔符,并且每个每个数据项用“”括起
2)用WRITE语句写入的正数前面没有空格。
例如:
Write#1,"One","Two",123
文件内容:
"One","Two",123
例:
在磁盘上建立一个电话号码本文件,存放单位名称和电话。
PrivateSubForm_Click()
Open“c:
\tel.dat”ForOutputAs#1
Unit$=InputBox(“EnterUnit:
”)
WhileUcase(Unit$)<>”DONE”
Tel$=InputBox(“Telephonenumber:
”)
Write#1,unit$,tel$
Unit$=InputBox(“Enterunit:
”)
Wend
Close#1
End
EndSub
可用记事本查看。
当用Print语句写入时的区别。
PrivateSubForm_Unload(CancelAsInteger)
Open"out7.txt"ForOutputAs#1
Print#1,Op1.Value,Op2.Value,Text1.Text
Close#1
EndSub
更为一般的:
将所要输入的记录先定义为一种类型——记录类型,其中每个分量称之为它的一个域,这种类型先给其一个名,自定义的记录型。
要访问其中一个分量用:
变量.域名
其中,变量必须为所定义的记录型.
定义记录类型:
工程→添加模块→模块→添加
type类型名
分量1 AS类型
分量2 AS 类型
……
endtype
Typestudent
nameAsString*10
ageAsInteger
sexAsString*4
EndType
Dimstu()Asstudent,nAsInteger
PrivateSubForm_Load()
n=Val(InputBox("学生人数"))
ReDimstu(n)
Fori=1Ton
stu(i).name=InputBox("请输入"&i&"姓名")
stu(i).age=Val(InputBox("年龄"))
stu(i).sex=InputBox("性别")
Next i
Open"C:
\123.txt"ForoutputAs#1
Fori=1Ton
Print#1,stu(i).name,stu(i).age,stu(i).sex
Nexti
Close#1
EndSub
例:
保存文本框要点:
如何查看结果?
?
假定文本框的名称为txtTest,文件名为TEST.DAT。
方法1:
把整个文本框的内容一次性地写入文件。
Open“TEST.DAT”ForOutputAs#1
Print#1,txtTest.Text
Close#1
方法2:
把整个文本框的内容一个字符一个字符地写入文件。
Open"TEST.DAT"ForOutputAs#1
Fori=1ToLen(TxtTest.Text)
Print#1,Mid(TxtTest.Text,i,1);
PrintMid(TxtTest.Text,i,1),
Nexti
Close#1
函数Len(串)取串长
函数Mid(串,起始位置,字符数)从指定位置取子串
3.关闭文件
Close[[#]文件号][,[#]文件号]...
例如,Close#1,#2,#3
Close
关闭所有打开的文件
14.4.2顺序文件的读操作:
1.Input语句
格式:
input#文件号,变量表
把读出的每个数据项分别存放到所对应的变量。
以“,”为分界符。
例:
Open"C:
\123.txt"ForinputAs#1
Fori=1Ton
Input#1,stu(i).name,stu(i).age,stu(i).sex
Next
Close#1
Fori=1Ton
?
stu(i).name,stu(i).age,stu(i).sex
Next
2.LINEINPUT#文件号,字符串变量
读一行到变量中,主要用来读取文本文件,以回车为分界符。
字符串变量用来接收从顺序文件中读出的字符行。
前提:
原始文件如何提供?
Open“C:
\123.text”forInputas#2
WhilenotEof
(2)
Lineinput#2,S
Text1.text=text1.text+s+chr(13)+chr(10)
Wend
Close#2
在文件中读取位置?
?
3.Input$函数
格式:
Input$(n,#文件号)
返回从指定文件中读出的N个字符的字符串
x$=Input$(100,#1)
不把回车-换行序列看作是一次输入操作的结束标志。
PrivateSubForm_Click()
Q$=InputBox(“请输入要查找的字符串:
”)
Open“c:
\autoexec.bat”ForInputAs#1
X$=Input$(LOF
(1),1)‘把整个文件内容读入变量X$
Close
Y=InStr(1,X$,Q$)
Ify<>0Then
Print“找到字符串”;Q$
Else
Print“未找到字符串”;Q$
EndIf
EndSub
14.5随机文件
前提知识:
由若干数据项组成的一条记录即自定义的一种数据类型,这种数据包含需要的数据项
Type类型名
子数据项AS类型
子数据项AS类型
……
Endtype
TypeRecord
IDAsInteger
NameAsString*20
EndType
Dim变量AS自定义类型
如:
DimRecasRecord
不论读写,都不能直接操作Rec
应该操作:
Rec.子项Rec.IDRec.Name
14.5.1随机文件的打开与读写操作
1.随机文件的写操作
分为以下4步:
(1)定义数据类型
随机文件由固定长度的记录组成,每个记录含有若干个字段。
(2)打开随机文件
Open"文件名"ForRandomAs#文件号[Len=记录长度]
打开后既可读又可写。
随机文件的长度是固定的,应在打开文件的同时指定记录长度,“记录长度”为各个字段长度之和,以字符为单位,若省略“Len=记录长度”,则默认长度为128个字节。
通过直接计算得到
通过函数得到Len(记录型变量)
Open"TESTFILE"ForRandomAs#1Len=Len(MyRecord)
(3)写操作
Put[#]文件号,[记录号],变量名
将一个记录变量的内容写到文件指定的记录位置处。
1)忽略记录号,则表示在当前记录后的位置插入一条记录。
但逗号不能省:
Put#2,,Filebuff
2)如果要写入的字符串变量是一个定长字符串,则除写入变量外,Put语句还写入两个字节的描述符,因此由LEN子句所指定的记录长度至少应比字符串的实际长度多两个字节。
还有其它情况。
3)关闭文件与顺序文件同。
2.随机文件的读操作
Get#文件号,[记录号],变量名
忽略记录号,则读出当前记录后的那一条记录。
例:
建立随机文件。
TypeRecord
IDAsInteger
NameAsString*20
EndType
DimMyRecordAsRecord
Open"TESTFILE"ForRandomAs#1Len=Len(MyRecord)
ForRecordNumber=1To5
MyRecord.ID=RecordNumber
MyRecord.Name="MyName"
Put#1,RecordNumber,MyRecord
NextRecordNumber
Close#1
例:
用Get命令读出上例建立的随机文件中第三条记录。
TypeRecord
IDAsInteger
NameAsString*20
EndType
DimMyRecordAsRecord
Open"TESTFILE"ForRandomAs#1Len=Len(MyRecord)
Position=3
Get#1,Position,MyRecord
PrintMyrecord.Id,Myrecord.Name
Close#1
3.SEEK函数
SEEK(文件号)
随机文件:
返回下一个要写入或读出的记录号;二进制文件或顺序文件:
返回下一个写入或读出的字节位置。
4.SEEK命令
Seek[#]文件号,位置
设置下一个要写入或读出的位置。
例:
建立一个文件名为STUDENT.DAT二进制文件。
SubForm_Click()
DimNameAsString*10
Open"Student.Dat"ForBinaryAs#1
Do
NAME=InputBox("请输入学生姓名:
")
Put#1,,NAME
YES=InputBox("继续输入吗?
(Y/N)")
LoopWhileUCase(YES)="Y"
Close#1
EndSub
例:
用INPUT函数读出上例建立的文件。
SubForm_Click()
DimNameAsString*10
Open"Student.Dat"ForBinaryAs#1
Flength=Lof
(1)
Char=Input(Flength,#1)
PrintChar
Close#1
EndSub
14.5.2随机文件中记录的增加与删除
1.增加记录
即在文件的末尾附加记录。
方法:
先找到文件最后一个记录的记录号,然后把要增加的记录写到它的后面。