《新编Visual-Basic程序设计教程》第13章_第1页
《新编Visual-Basic程序设计教程》第13章_第2页
《新编Visual-Basic程序设计教程》第13章_第3页
《新编Visual-Basic程序设计教程》第13章_第4页
《新编Visual-Basic程序设计教程》第13章_第5页
已阅读5页,还剩89页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第13章

文件操作文件概述文件的打开与关闭顺序文件随机文件二进制文件文件基本操作文件系统控件文件综合上机练习题13.1文件概述文件通常存储在光碟、磁盘等外部介质上,在使用时我们才会将其调入到内存中。数据文件是指驻留在磁盘或其他外部介质上的一个有序数据集,可以是文本文件、可执行程序文件、数据库文件等(既我们使用计算机时能够在外介质上找到的文件,也是我们接下来要学习的重点)。13.1.1文件设备在介绍文件之前,让我们一起来了解一下计算机中用来存储文件的设备“硬盘”。我们已经知道了计算机一些外部设备的作用,比如说,键盘是用来向计算机内输入数据的设备,所以我们称键盘为输入设备。显示器是用来显示计算机内数据信息的设备,所以我们称显示器为输出设备。但是那个被封锁在计算机里的黑匣子(也就是硬盘)应该归属于什么设备呢?其实这个问题并不难于回答,只要我们把自己的位置放在计算机的核心部分CPU,就能够非常清晰的区分开一个设备是输入设备还是输出设备,或其他设备。我们之所以称键盘是输入设备,是因为我们可以通过键盘向计算机的CPU(中央处理器)进行数据输入,因此我们称键盘为输入设备,而显示器是用来将中央处理器中的数据显示给用户的设备,因此我们称其为输出设备。可对于硬盘等外部存储器来说,我们有时需要把数据从硬盘读取到中央处理器,这时的硬盘就像计算机键盘一样为中央处理器提供了数据,因此我们把它看作是一个输入设备。而当我们为了把CPU中的数据长期保存,将其写入到硬盘中去的时候,硬盘的作用就类似于显示器,都是用来接收CPU发送的数据的,这时我们称硬盘为输出设备。文件是存储在硬盘上、一组相关数据的有序集合。因此它拥有和磁盘相似的属性。当我们从文件中读取数据时,我们就可以把该文件当作一个输入设备来使用;如果我们把内存中的数据数据写入到一个文件中,这时我们可以把该文件当作一个输出设备来使用。13.1.2文件的结构为了有效地存取数据,数据必须以某种特定的方式存放,这种特定的方式称为文件结构。VisualBasic中文件由记录组成,记录由字段组成,字段由字符组成。(1)字符(Character):是构成文件最基本的单位。可以是数字、字母、特殊符号或单一字节。这里所说的“字符”特指西文字符,一个西文字符在磁盘文件中用一个字节存放。如果是汉字字符,包括“全角”符号,用两个字节存放。(2)字段(Field):也称域。由若干个字符组成,用来表示一项数据。例如:姓名“张语真”,邮政编码“123456”这些都是字段。(3)记录(Record):由一组相关的字段组成。例如在学籍档案中,每个学生的姓名、性别、家庭地址、电话号码、邮政编码等构成一个记录,如下表所示。在VisualBasic中,以记录为单位来处理数据。姓名性别家庭地址电话号码邮政编码张语真女自由大道12345678123456记录(4)文件(File):文件由纪录构成,一个文件中含有一个以上的记录。例如,在学籍档案中存有1000个学生的信息,每个人的信息是一个记录,这1000个记录即构成了一个文件。13.1.3文件的分类在VB中根据文件的结构和访问方式,可将文件分为三类:顺序存取文件、随机存取文件和二进制存取文件。下面分别予以介绍。1.顺序存取文件顺序存取是将要保存的数据,依序逐个字符转成ASCII字符,然后存入磁盘。以顺序存取的方式保存数据的文件叫做顺序存取文件,简称顺序文件。顺序文件存储格式如下图所示。顺序文件存储格式通常,记录与记录之间的分界字符为回车符,记录中字段与字段之间的分界字符为逗号。在顺序文件中查找某个记录必须从文件头开始找起,逐个比较,直到找到目标为止。若要修改某个记录,则需将整个文件读出来,修改后再将整个文件写回磁盘,因此很不灵活。但由于顺序文件是按行存储,所以它们对需要处理文本文件的应用程序来说就是非常理想的了。例如,一般的文本文件(*.txt文件)都是顺序文件。顺序文件的优点是操作简单,缺点是无法任意取出某一个记录来修改,一定得将全部数据读入,在数据量很大时或只想修改某一条记录时,则显得非常不方便。顺序文件的特点是:结构简单,但不能灵活的存取和增减数据,因而适合存放有一定的规律且不经常修改的数据。主要优点是占用空间少,容易使用。2.随机存取文件又称直接存取文件,简称随机文件或直接文件。与顺序文件不同,在访问随机文件中的数据时,不必考虑各个记录的排列顺序和位置,可以根据需要访问文件中的任何一个记录。随机文件很像一个数据库,它由大小相同的记录组成,每个记录又由字段组成,字段中存放着数据。其存储结构如下图所示。随机文件存储格式每个记录前都有记录号表示此记录开始。在读取文件时,只要给出记录号,就可迅速找到该记录,并将该记录读出;若对该记录做了修改,需要写到文件中时,也只要指出记录号,新记录将自动覆盖原有记录。所以,随机文件的访问速度快,读、写、修改灵活方便,但由于在每个记录前增加了记录号,从而使其占用的存储空间增大。3.二进制文件在二进制文件中的数据均以二进制方式存储,存储单位是字节(随机文件按记录存取,顺序文件按行存取)。在二进制文件中,能够存取任意所需要的字节,可以把文件指针移到文件的任何地方,因此,使用二进制文件和使用计算机内存中的数据是一样的。所以,这种存取方式最为灵活,但二进制文件不能用普通的字处理软件编辑。13.2文件的打开与关闭在VB中进行文件操作的基本步骤如下:(1)打开(或建立)文件在我们使用一个文件之前,必须先打开或建立这个文件。如果我们要处理的文件已经存在,则打开该文件;如果不存在,则建立该文件。(2)对文件进行数据处理(读、写操作)在已经打开的文件上进行输入输出操作。就如上一节中我们提到的,把内存中的数据传送到相关的外部设备(例如磁盘)并作为文件存放的操作叫做写数据,而把文件中的数据传送到内存中的操作叫做读数据。(3)关闭文件关闭文件,即释放文件的控制权,并释放文件处理时所占用的内存。13.2.1文件的打开(建立)如前所述,在对文件中的数据进行操作之前,我们必须先打开或建立文件。同时要通知操作系统对文件进行读操作还是写操作,将数据存到什么地方。打开文件用Open语句。其使用语法如下:Open文件名[For模式][Access访问方式][Lock]As[#]文件号[Len=记录长度]Open语句的作用是为文件的输入输出分配内存缓冲区,并指定该缓冲区使用的存取方式。说明:一、Open语句中的Open、For、Access、As和Len为关键字,参数“文件名”是指要打开的文件,可包含驱动器名及路径名。其他几个参数含义如下:(1)“模式”用来说明文件打开的方式,即指定文件的输入输出方式,它可以为以下几种操作之一:Output(输出):指定Open语句以顺序方式打开文件,并且将该文件当作一个输出设备来使用,相当于由内存向硬盘写数据。Input(输入):指定Open语句以顺序方式打开文件,并且将该文件当作一个输入设备来使用,相当于由硬盘向内存读数据。Append(追加):指定Open语句以顺序方式打开文件,并且将该文件当作一个输出设备来使用。与Output模式的不同之处在于,当用Append模式打开文件时,文件指针被定位在文件的末尾。如果对文件进行写操作,相当于将数据添加在文件尾部。Random(随机):指定Open语句以随机存取方式打开文件,此项为“模式”参数的默认值。在随机模式中,如果没有Access子句,则执行Open语句时,VB试图按下列顺序打开文件:(a)读/写;(b)只读;(c)只写。Binary:指定以二进制方式打开文件。在这种模式下可以用Get和Put语句对该文件中任何一个字节位置上的信息进行读写操作。(2)“访问方式”说明打开文件所允许的操作,有三种方式:Read:只读方式。Write:只写方式。ReadWrite:读写皆可,只适用于随机文件、二进制文件和顺序文件的Append模式。“访问方式”制定了能够在打开的文件中进行的操作。如果要打开的文件已经被其他进程打开,则VB不允许再次为该文件制定“访问方式”,否则在执行Open语句时会产生错误信息。(3)Lock参数是指明其他进程对打开文件所允许的操作,可以为以下几种操作之一:(4)“文件号”是一个1~511的整数,用于表示这个文件。执行Open语句时,打开文件的文件号与一个具体的文件相关联,其他输入输出语句或函数就是通过文件号与文件发生关联。(5)记录长度是一个整型数,故其长度不能超过32767。对顺序文件来说,它是指内存缓冲区分配的字符个数;对随机文件来说,它是文件中单个记录的长度。对于二进制文件将忽略Len子句。LockShared:其他进程可对此文件进行任何读写操作。LockRead:不允许其他进程读此文件。LockWrite:不允许其他进程写此文件。LockReadWrite:不允许其他进程对此文件进行任何操作。二、Open语句兼有打开和创建文件两种功能。如果我们为输入(Input,特指把磁盘文件的数据向内存输入)打开的文件未找到,VB将会产生“文件未找到”错误;如果为输出(Output)、追加(Append)或随机(Random)模式打开的文件不存在,则建立相应的磁盘文件。下面是一些用Open语句打开或建立文件的例子:该语句以输出方式打开C盘根目录上的文件abc.txt(如果不存在就建立该文件),即把文件c:\abc.txt当作一个输出设备来使用,准备对其进行写操作,并为该设备指定文件号为1号。以追加输出方式打开C盘yxz目录下的文件abc.txt,并指定文件号为5。该语句以输入方式打开C盘根目录上的文件abc.txt(如果不存在就产生“未找到文件”错误),即把文件c:\abc.txt当作一个输入设备来使用,准备对其进行读操作,并为该设备指定文件号为7号。Open"c:\abc.txt"ForOutputAs#1Open"c:\xyz\abc.txt"ForAppendAs#5Open"c:\abc.txt"ForInputAs#7以上几个例子打开的文件都是按照顺序方式输入输出的。上例先把文件名赋给一个变量FileName$,然后以随机模式打开该文件,并且制定该文件中单个记录的长度为256个字节。DimFileName$FileName$="c:\MyFile.dat"OpenFileNameForRandomAs#1Len=25613.2.2文件的关闭对文件操作完之后,要关闭文件,其语法:Close[#文件号1][,#文件号2]……若Close语句后无文件号,则关闭所有打开的文件。如果我们使用以下语句打开了一个文件:则可用以下语句来关闭该文件设备。Open"c:\abc.dat"ForRandomAs#1Len=256Close#113.3顺序文件一般不为顺序文件制定Len子句参数。因为对于顺序文件来说,记录长度这一概念没有实际意义。一般也不为顺序文件制定Access子句参数。因为对于顺序文件的读写操作模式已经在For后的“模式”参数中作出了明确的规定。顺序文件按存储单元进行存储,它通常是一个文本文件,数字和字符均以ASCII码形式保存。下面讨论顺序文件的操作语句。13.3.1顺序文件的打开在对任何文件进行操作之前,必须打开文件,同时要通知操作系统对文件进行读操作还是写操作,将数据存到什么地方。顺序文件也不例外,打开文件的方法已经在上一节中做了详细的介绍这里就不再赘述。只是有一些细节问题需要注意。13.3.2顺序文件的写操作要建立一个顺序文件或打开一个顺序文件,向文件中写数据,应该用Output模式打开文件,然后用输出命令写入数据。以Output模式打开文件,就是建立文件;若文件已存在,则删除旧文件,建立新文件。以Append模式打开文件与此很相似,二者的差别在于:以Append模式打开文件时,如果该文件已经存在,VB并不删除它,随后的输出命令把新行追加到该文件尾部。写文件的输出命令有Print和Write两种,其意义如下。1.Print#语句Print#文件号,[Spc(n)|Tab(n)]字段1[;|,][Spc(n)|Tab(n)][字段2[;|,]……Print#语句的功能是,把数据写入到指定的文件设备中去。前面的章节中,我们曾经多次用到Print方法,Print#语句与Print方法的功能基本类似,不同的是,Print方法的输出对象是窗体、图片框等屏幕设备或Printer(打印机设备),而Print#语句所“写”的对象是文件设备。在上面的格式中,“文件号”的含义同前,数据被写入该文件号代表的文件中。其他参量,包括Spc函数、Tab函数和分号、逗号的含义都与Print方法相同,这里就不再赘述。

例如:在C盘根目录上建立文本文件FirstFile.txt并为其关联到文件号1,然后把字符串常量"HelloWorld!!!"和变量A的内容写到文件号为1的文件中,然后使用Close语句关闭该文件设备。而

则是把常量与变量的内容“写”到窗体对象这个屏幕输出设备上去。Open"c:\FirstFile.txt"For0utputAs#1A$="Iamsohappy."Print#1,"HelloWorld!!!",AClose#1Print"HelloWorld!!!",A下面我们就一起来看一个将文本框中的数据进行保存的例子:例13.1建立一个单窗体VB工程。在窗体对象Form1上添加一个文本框控件Text1和两个个命令按钮对象Command1和Command2,如下图所示。要求实现以下功能,在文本框中输入一些文字,鼠标单击命令按钮后弹出一个对话框,在对话框中输入文件的保存位置,然后在该位置以顺序文件方式保存文本框中的文字数据。顺序文件保存程序(1)向窗体对象上添加各个控件后,按照下表改变各控件相关属性。Name属性Caption属性MultiLine属性ScrollBars属性Text1无True3Command1保存文件无无Command2退出程序无无例13.1各控件属性表(2)编写以下程序代码:PrivateSubCommand1_Click()DimFileNameAsStringFileName=InputBox("请输入文件的保存位置","保存","c:\abc.txt")OpenFileNameForOutputAs#1Print#1,Text1.TextClose#1EndSub

PrivateSubCommand2_Click()EndEndSub(3)测试程序的运行结果。当程序运行时,向文本框中输入字符信息,比如“我是中国人,我热爱我的祖国。”然后点击保存程序命令按钮。在弹出的对话框的文字区中输入文件保存的位置,默认值为:c:\abc.txt,然后用记事本程序打开该文件,我们能够看到如下图所示结果。程序运行结果2.Write语句前面我们曾提到,除了可以利用Print#语句向顺序文件输入数据外,还有另外的方法,这个方法就是Write语句。其格式为:Write语句的使用和Print#语句基本一样,例如:把变量A、B、C的值写入文件号为1的文件中。在Write语句中,“文件号”和“字段”的概念都和Print#语句一致,在此不再赘述。使用Write语句时,文件也必须是以Output或Append模式打开的顺序文件,各字段之间必须用逗号分开。Write语句的功能和Print#语句基本相同,但有以下两点主要区别,望读者注意:(1)当用Write语句向文件写数据时,数据在磁盘上以紧凑格式存放,且能自动地在数据项之间插入逗号,并给字符串加上双引号。一旦该语句最后一个参变量被写入到文件中后,就在这一行的末尾插入一个换行符,标识着该记录的结束。Write#1,A,B,CWrite#文件号,字段1,……(2)使用Write语句写入到顺序文件中的整数前没有空格。例13.2

在磁盘上建立一个顺序文件,使用Write语句向该文件中输入若干数据,然后用记事本应用程序打开该顺序文件,观察文件内数据的存储方式。程序代码如下:PrivateSubForm_Load()DimAAsIntegerDimBAsDoubleDimCAsStringA=3:B=-108.98:C="2008年奥运会在北京举办。"Open"c:\myfile.txt"ForOutputAs#1Write#1,A,B,CWrite#1,"我是中国人,我深爱着自己的祖国。"Close#1EndSub在本程序执行后,我们在计算机硬盘C盘根目录上可以找到一个文本文件(顺序)myfile.txt。如果使用记事本应用程序将其打开观看其内容,其结果如下图所示。例13.2程序运行结果以上运行结果验证了Write语句数据输出的特点:数据在磁盘上以紧凑格式存放,且能自动地在数据项之间插入逗号,并给字符串加上双引号。一旦该语句最后一个参变量被写入到文件中后,就在这一行的末尾插上一个换行符号。标识着该记录的结束;写入到顺序文件中的整数前没有空格,这样进行数据保存有利于从文件中读取单个数据项。13.3.3顺序文件的读操作要读顺序文件的内容,应该以Input模式打开该文件,然后从中读取数据。读数据的操作由Input#语句、LineInput#语句和Input$函数三种方法来实现。1.Input#语句Input#语句的作用是从文件中读取数据,并且把读出的数据赋值给指定的字段变量。其格式如下:例如,语句的功能是从1号文件中读取3个数据,并将其分别赋值给变量A、B和C。Input#文件号,字段1[,字段2]{,……}Input#1,A,B,C例13.3

编写程序,用Input#语句来读取例13.2保存在磁盘文件中的数据,并将读出的数据在窗体对象上打印输出。程序如下:PrivateSubForm_Load()Open"c:\myfile.txt"ForInputAs#1Input#1,a,b,c,dMe.ShowPrinta,bPrintcPrintdClose#1EndSub本程序运行结果如下图所示。程序运行结果2.LineInput#语句LineInput#语句的作用是,从顺序文件一次读出一行字符串数据到指定变量。其语法格式如下:语法格式中“文件号”含义同前。字符串变量的作用是用来接收LineInput#语句读出的字符串数据。LineInput#语句与Input#语句的作用基本相似,主要区别是:Input#语句每次从顺序文件中读取一个数据项,而LineInput#语句每次从文件中读取一行数据,并自动省略每行数据后的回车换行符。正因为LineInput#语句的这些特点,所以它经常被用来处理文本文件。下面我们一起来看一个具体的例子。LineInput#文件号,字符串变量在编制程序前,我们有必要了解几个与文件操作有关的函数。它们分别是:(1)LOF()函数以字节方式返回被打开文件大小。其调用语法如下:如LOF(1)返回#1文件的长度。(2)LOC()函数返回被打开文件的当前位置。其调用语法如下:对于顺序位置的计算以128字节为单位,返回当前位置是第几个128字节;对于随机文件,它返回当前读写的记录号;对于二进制文件,返回当前的字节位置。(3)EOF()函数返回值指出读文件过程中是否到了文件末端。其调用语法如下:返回True,则到达文件末端;否则返回False。LOF(文件号)LOC(文件号)EOF(文件号)(4)FreeFile()函数返回程序中尚未被使用的文件号。在我们编制的程序中打开的文件有多个时,这个函数将变得尤为重要。还有一点要特别的注意,对于顺序文件,读写操作不能同时进行。每进行一次读或写操作,都必须重新打开文件,读或写完之后再关闭文件。例13.4

编写一个类似于Windows操作系统记事本应用程序一样的文字编辑软件。要求可以打开磁盘上的文本文件,在对文件内容进行编辑后还要能保存文件。其操作界面如下图所示。简单文本文件处理程序(1)向窗体对象上添加上各个控件后,按照下表改变各控件相关属性。Name属性Caption属性MultiLine属性ScrollBars属性Text1无True3Command1打开文件无无Command2保存文件无无例13.4各控件属性表(2)编写以下程序代码。PrivateSubCommand1_Click()location=InputBox("Open","打开文件")Iflocation<>""ThenOpenlocationForInputAs#1WhileNotEOF(1)'如果还没有读到文件尾,就不停止数据的读取操作。LineInput#1,TextText1.Text=Text1.Text+Text+Chr(13)+Chr(10)'人为加上回车换行符。WendClose#1EndIfEndSubPrivateSubCommand2_Click()location=InputBox("Saveas","文件保存")Iflocation<>""Thenfilenum=FreeFile() '利用FreeFile函数得到尚未被使用的文件号。OpenlocationForOutputAsfilenumPrint#filenum,Text1.TextClose#filenumEndIfEndSub3.Input$函数Input$函数返回从指定文件中读出的n个字符组成的字符串,其语法如下:例如,语句从1号文件中读取前20个字符,并将其赋给字符串变量x$。Input$函数有些类似于C语言中的fread函数,都是把文件当作一个“二进制数据流”,因此在使用Input$函数对文件进行数据读操作之前应该以二进制模式打开文件。Input$函数的作用就是从这个数据流中读取指定的数据量,如上例中的20个字符。因此如果我们要完全读取一个文件的内容的话,使用Input$函数对文件进行读操作会获得更高的效率。x$=Input$(n,#文件号)x$=Input$(20,#1)例如,我们可以把例13.4中读取文件的程序代码改编如下:PrivateSubCommand1_Click()location=InputBox("Open","打开文件")Iflocation<>""ThenOpenlocationForBinaryAs#1 '以二进制方式打开文件,以便可以使用Input$'函数正确的进行文件读取。Text1.Text=input$(LOF(1),#1) '使用Input$函数读取1号文件中的所有数据。Close#1EndIfEndSub通过以上改编,我们会发现,在对数据量比较大的文件进行读操作时(比如说,文件中有600000行数据),使用Input$函数进行数据读取的速度要明显高于LineInput语句。13.4随机文件在本章第一节中我们曾经描述了随机文件的结构。我们知道随机文件的结构很像数据库,对随机文件的操作实际上是对文件中的记录进行操作,每个记录都有记录号并且记录长度全部相同。那么无论是从内存向磁盘写数据,还是从磁盘读数据,都需要事先定义内存空间。而VB中内存空间的分配是靠变量说明来进行的,所以不管是读操作还是写操作都必须事先在程序中定义变量,且该变量要定义成与随机文件中的一条记录相同的类型,一条记录又是由多个字段组成的,每字段有不同的类型和长度。因此在程序中用来保存记录的变量,在其说明部分应采用用户自定义类型说明语句,首先定义记录的类型结构,然后再将变量说明成该类型,这样就为这个变量申请了内存空间,用于存放随机文件中的一条记录。13.4.1定义记录类型我们提到过,随机文件是由固定长度的记录组成,每个记录含有若干个字段。记录中各字段存放在一个记录类型中,记录类型用Type…EndType语句定义。且定义记录类型时,Type…EndType语句通常在标准模块中使用,如果在窗体模块中进行数据类型的定义,则应该在其前面加上Private关键字。关于记录类型的定义与使用方法,已经在前面章节中进行了详细的介绍,这里就不再赘述。只举如下一例:PrivateTypeStudTypeNumAsString*8NameAsString*12AgeAsIntegerClassAsString*5EndTypeDimaStudentAsStudType13.4.2随机文件的打开(建立)我们前面提到过,在使用一个文件进行数据的输入与输出操作时,必须先打开这个文件。对于随机文件而言,首先要以随机模式打开文件,其使用语法如下:Open文件名ForRandomAs#文件号[Len=记录长度]与顺序文件不同的是,随机文件读、写两种操作都用Random模式打开,一经打开即可同时进行读、写操作。也就是说,对随机文件进行某种操作后不必关闭文件就可进行另一种操作。因此我们才称其为随机读写文件,即随机文件。另外,在Open语句中还要指明文件中单个记录的长度,该长度等于记录中各字段长度之和,且以字节为长度单位。如果省略“Len=记录长度”子句,则以128个字节作为记录长度的默认值。13.4.3随机文件的读写操作1.文件指针在文件被打开后,将自动生成一个文件指针。文件的读写操作都是在该指针指定的位置进行的,比如:在我们使用Append模式打开一个文件时,该文件的文件指针就指向被打开的文件的末尾。在我们以顺序模式使用文件时,我们是没有必要考虑文件指针的位置的。因为顺序文件,读写操作不能同时进行。每进行一次读或写操作,都必须重新打开文件,读或写完之后再关闭文件。这也就意味着,我们每次使用顺序文件都是把该文件完全读入内存缓冲区,然后再对它全部的数据进行读写操作。也正因为此,使用顺序文件时,我们不必过多考虑它的文件指针的位置。对于随机文件和二进制文件,要求我们能够对该文件中任何一个记录进行随机的读写操作,这也就要求我们能够人为的改变文件指针的位置。因此也就用到了Seek语句与Seek函数。(1)Seek()函数,使用语法如下:该函数用来返回当前文件指针的位置。对于随机文件返回当前记录号,对于二进制文件返回从文件头算起的字节数。(2)Seek语句,使用语法如下:该语句用来将文件指针定位到指定的位置,对于随机文件“位置”指的是一个记录号,对于二进制文件指定位到从文件头算起的某个字节位置。Seek(文件号)Seek#文件号,位置2.随机文件的写数据操作向随机文件中写数据用Put语句,其使用语法如下:其中文件号含义同前。记录号是可选的,其取值范围是1~231-1。该语句是将一个记录变量的内容写入所打开的磁盘文件中指定的记录位置处。记录号必须是大于1的整数,表示写入的是第几条记录;若不指定记录号,则表示将变量内容写在下一记录位置,即最近执行Get或Put语句后的下一个记录位置,或最近一个Seek语句所指定的文件位置。Put#文件号,[记录号],记录变量3.随机文件的读数据操作使用Get语句从随机文件读取数据,其使用语法如下:Get#文件号,[记录号],记录变量其中,记录变量的数据类型必须同文件中记录的数据类型一致。该语句是从指定文件中,将一条由记录号指定的记录内容读入记录变量中。记录号概念同前,表示对第几条记录进行操作,如果忽略记录号,则表示读出当前记录后的那一条记录。例如:表示把1号文件中第一个记录读到aStudent变量中。既然我们已经了解了如何对随机文件进行读写操作,那么我们一起来看如下一个简单的程序。Get#1,1,aStudent例13.5建立如下图所示应用程序,然后按照下表设定各控件相关属性。Name属性Caption属性Text属性Text1~Text4无空Command1添加记录无Command2显示记录无Command3程序记录无Label1姓名无Label2学号无Label3年龄无Label4班级无Label5显示记录无Picture1无无随机文件的读写操作

例13.5各控件属性表要求本程序能够实现,类似于简单的数据库的功能。即能够向文件中插入新的记录,并且能够读出指定记录号的一个数据记录的各字段的数据内容。设定好相关属性后,打开代码窗口编写以下代码:PrivateTypeStudent'自定义一个记录型数据类型StudentnameAsString*10NumAsString*8ageAsIntegerclassAsString*8EndType

DimaStudentAsStudent'声明Student类型变量aStudentDimlastPositionAsInteger‘定义用来存放文件中最后一个记录的记录号的变量

PrivateSubForm_Load()'以随机方式打开文件OpenApp.Path+"\student.dat"ForRandomAs#1Len=Len(aStudent)lastPosition=LOF(1)/Len(aStudent)'计算文件中记录的个数EndSub

PrivateSubCommand1_Click()IfText3.Text<>""ThenlastPosition=lastPosition+1aS=Text1.TextaStudent.Num=Text2.TextaStudent.age=Cint(Text3.Text)aStudent.class=Text4.TextPut#1,lastPosition,aStudent'把新记录添加到文件中Text1.Text=""Text2.Text=""Text3.Text=""Text4.Text=""MsgBox"新记录添加完成!"EndIfEndSubPrivateSubCommand2_Click()DimdispPositionAsStringdispPosition=InputBox("请输入您要查询的记录号,"_+Chr(13)+Chr(10)+"且记录号数值不可超过"+CStr(lastPosition),"输入记录号")IfIsNumeric(dispPosition)ThenIfCInt(dispPosition)>0AndCInt(dispPosition)<=lastPositionThenGet#1,dispPosition,aStudent'从文件指定位置读取一个记录到记录变量aStudentPicture1.ClsPicture1.Print"姓名:";aSPicture1.Print"学号:";aStudent.NumPicture1.Print"年龄:";aStudent.agePicture1.Print“班级:”;aStudent.classElsePicture1.Print"记录号错误"EndIfElseMsgBox"请输入数值信息。"EndIfEndSubPrivateSubCommand3_Click()EndEndSub

PrivateSubForm_Unload(CancelAsInteger)Close#1'程序结束时关闭文件回收资源EndSub程序完成后,按F5键运行程序,在4个文本框中填写相应数据,然后点击“添加记录”命令按钮就会向1号文件的文件尾添加一个新的记录。然后清空4个文本框中的数据,等待下次输入。如果点击“显示记录”命令按钮,那么会弹出一个InputBox对话框,要求我们输入欲显示其内容的记录号。如果输入一个记录号点击“确定”,则在Picture1图片框上将该记录的各字段内容打印输出。其运行结果如右图所示。程序运行结果13.5二进制文件二进制文件中的内容以字节为基本单位进行存取操作的。与随机文件相同的是:二进制文件打开后,读与写操作可同时进行。因此,二进制访问能提供对文件的完全控制。此外,因为二进制文件存储的信息和内存数据具有完全一致的信息格式,因而不需要再对数据进行编码转换。因此,当需要保持文件大小尽量小时,应使用二进制文件。对二进制文件操作时所使用的语句和对随机文件进行操作的语句与方法基本相似,都是使用Seek语句、Seek函数、Put方法和Get方法。但又稍有区别,让我们一起来看看其具体操作方法。13.5.1二进制文件的打开(建立)与其他几种文件模式的打开语句一样,在VB中打开二进制文件,还是使用Open语句。其格式如下:前面我们说过,二进制文件与随机文件的相同点是,在文件以二进制模式打开后,读写操作可同时进行。可它们还是有区别的,二进制文件访问中的Open语句与随机存取的Open语句不同,它没有指定Len部分。这是因为,在Binary模式下进行文件操作时,存取数据的单位是字节,而不是像随机文件一样以记录为基本单位。所以,如果我们在二进制文件访问的Open语句中包括了记录长度,则该长度将被忽略。Open文件名ForBinaryAs#文件号13.5.2向二进制文件中写数据向二进制文件写数据仍然使用Put#语句,其语法如下:其中“文件号”概念同前,“位置”是按字节计数的读写位置。若默认,则文件指针从头到尾顺序移动。Put#语句向文件写的字节数等于变量长度。Put#文件号,[位置],变量13.5.3从二进制文件中读数据从二进制文件读数据仍然使用Get#语句,其语法如下:其中“文件号”和“位置”概念同前,Get#语句从二进制文件中读出的字节数等于变量长度。在二进制文件读写的过程中,也常常用到Seek函数和Seek语句来定位和返回当前文件指针:(1)Seek()函数

使用语法如下:对于二进制文件来说,该函数用来返回以字节为单位、当前文件指针的位置。(2)Seek语句

使用语法如下:对于二进制文件来说,该语句用来将文件指针定位到recnumber字节处。Get#文件号,[位置],变量Seek(文件号)Seek文件号,recnumber13.5.4一个使用二进制模式对文件操作的具体实例在编制本实例程序之前,我们必须了解一些辅助知识,以便我们能够读懂为什么要这样编制程序。首先,我们要了解24位真彩色BMP格式位图的文件结构。BMP(Bitmap-File)图像文件是Windows采用的图像文件格式,在Windows环境下运行的所有图像处理软件都支持BMP图像文件格式。Windows系统内部各种图像绘制操作都是以BMP格式为基础的。一个典型的位图文件由4个部分组成:位图文件头(bitmap-fileheader)、位图信息头(bitmap-informationheader)、色表(colortable)和实际位图数据的字节阵列,其具体形式如下图所示。其中前面3个部分包含关于这个图形文件的信息,这不是我们这个程序讨论的重点,不对其进行详细说明。只要我们了解到这3个部分占据了一个24位真彩色BMP位图文件的前54个字节就可以了。位图文件头位图信息头色表实际位图数据典型BMP文件结构示意图对于一个24位真彩色BMP位图文件,其图像上每个点的色彩分别由图象文件“实际位图数据”部分中的三个字节,也就是24位来表示该点的RGB值,每个字节的值对应一种组成混合光的基础光(红色、绿色、蓝色)的强度。这一点非常类似于VB中的RGB函数。因此我们可以利用这类文件的这一特点来编写以下程序。例13.624位真彩色位图文件反色处理程序。要求该程序能够将选中的24位真彩色位图文件进行图像反色处理,所谓反色处理是指将每个点的颜色数据按位取反,即进行颜色反相,其效果如左图和右图所示。原始图像

经过反色处理的图像了解了图像反色这一概念和24位真彩色文图文件的格式后,我们就可以着手编写程序了。首先,按照下图所示添加窗体对象上的各个控件。程序中两个命令按钮对象的名称属性分别为Command1和Command2,然后按照图中所示分别为两个命令按钮对象设定标题属性。图中通用对话框对象的名称属性为CommonDialog1。图像反色处理程序设计窗体完成以上设定后为程序添加以下代码:'***************************************'24位真彩色位图文件,反色处理程序。'***************************************Dimdata()AsByte

PrivateSubForm_Load()CommonDialog1.Filter="位图文件|*.bmp"Form1.AutoRedraw=TrueEndSub

PrivateSubCommand1_Click()CommonDialog1.ShowOpenIfCommonDialog1.FileName<>""ThenOpenCommonDialog1.FileNameForBinaryAs#1'以二进制模式打开‘通用对话框所选择的文件。length=LOF(1)ReDimdata(length)'根据打开的文件的长度,重定义动态数组data()Fori=1TolengthGet#1,i,data(i)'将二进制文件中的每个字节的数据,读入到data()数组中去。Ifi>54Then'位图文件的文件头等格式数据总长度为54字节,不能对'这部分数据进行取反操作。除文件头等格式数据外,要对'该文件中所有数据进行取反操作。data(i)=Notdata(i)Put#1,i,data(i)'将每一个字节的实际位图数据进行取反后,'重新写入到1号文件。EndIfNextiPrintPrint"图片文件反色处理完毕,"Print"请打开";CommonDialog1.FileName;"观察效果。"Close#1EndIfEndSub

PrivateSubCommand2_Click()EndEndSub将以上代码添加到程序后运行程序,选择要对其进行反色操作的位图文件,然后再使用任何一种看图工具打开该位图文件,我们就可以看到该程序的运行效果了。13.6文件基本操作除了读写文件外,VisualBasic还提供了对文件进行删除、移动、复制和重命名等文件基本操作语句。13.6.1文件的删除在VB中对文件进行删除操作是通过Kill语句来实现的,其格式如下:Kill"文件名"参数“文件名”是一个用来指定欲将其删除的文件名字符串表达式。例如:由上面实例中第二个Kill语句我们可以看出,Kill语句支持多字符(*)和单字符(?)两种通配符号来完成对文件操作。Kill语句具有一定的危险性,因为使用Kill语句对文件进行删除操作时,不会将文件移到计算机的垃圾箱中,而是将文件彻底从硬盘删除掉。而且,在进行删除操作时不会给出任何提示,因此我们在程序中使用该语句时,一定要在删除文件前给出一些提示信息。Kill"D:\VB\datal.dat"'删除D盘VB目录内data1.dat文件。Kill"D:\VB\dat\*.*"'删除D盘VB目录内所有文件。13.6.2文件的复制和移动在VisualBasic中,文件的复制操作是通过FileCopy语句来实现的,其格式如下:FileCopy"源文件","目标文件"用FileCopy语句可以把源文件拷贝到目标文件,拷贝后两个文件的内容完全一致。例如:将当前目录下的一个文件拷贝到同一目录下的另一个文件。如果要将一个目录下某一文件拷贝到另一个目录下,则必须包括路径信息,例如:使用FileCopy语句时,我们必须保证源文件的存在和目标文件中路径信息的正确,且FileCopy语句中不能使用通配符号(*或?)。此外,FileCopy不能对已由VisualBasic打开的文件进行复制操作。VB并没有为我们提供专门的文件移动语句,但文件的移动操作其实可以分为以下两步操作:(1)复制文件。(2)将源文件删除。此外,用Name语句也可以实现文件的移动操作。FileCopy"source.doc","target.doc"FileCopy"c:\abc\source.doc","d:\xy\target.doc"13.6.3文件(目录)重命名在VB中,文件的改名可以通过Name语句来实现,其格式如下:Name"原文件名"As"新文件名"其中参数“原文件名”用来指定已经存在的文件名和位置,可以包含目录信息,“新文件名”参数用来指定改名后新的文件名和位置。值得注意的是,“新文件名”参数所指定的文件名不能是已经存在的文件名,否则会产生错误。在Name语句的参数中也不能使用通配符号(*或?)。此外,如果“新文件名”参数和“原文件名”参数中文件的路径信息不同,Name语句在改变文件名的同时还会对文件进行移动操作。例如:PrivateSubForm_Load()Name"c:\a.wav"As"d:\abc.wav"EndSub该例中Name语句的作用是,将C:盘根目录上的a.wav文件改名为abc.wav,然后将其移动到的D:盘根目录上。另外,除了能够改变某文件的名字外,Name语句还可以改变硬盘上某目录的名称。使用方法与对文件的操作一样,不再赘述。但有一点需要注意,对目录进行改名操作时,不能像操作文件一样进行跨驱动器移动操作,否则产生错误。13.7文件系统控件文件系统控件包括驱动器列表框、目录列表框和文件列表框。这三个列表框经常结合起来使用。驱动器列表框是下拉式列表框,默认时在用户系统上显示当前驱动器。当该控件获得焦点时,用户可以从中选择任何有效的驱动器标识符。目录列表框从最高层目录开始显示用户系统上的当前驱动器目录结构。在列表中上下移动时将依次突出显示每个目录项。文件列表框在运行时显示由Path属性指定的包含在目录中的文件。结合使用这三个控件和前面介绍的文件操作语句,可以编写完善的文件管理程序。13.7.1驱动器列表框和目录列表框驱动器列表框和目录列表框都是下拉式列表框,在工具箱中的图标如下图所示。驱动器列表框

目录列表框1.驱动器列表框驱动器列表框及后面介绍的目录列表框、文件列表框有许多标准属性,包括Enabled、FontBold、FontItalic、FontName、Fontsize、Height、Left、Name、Top、Visible、Width。而这些属性的作用都与其他一些控件基本类似,这里就不再赘述。此外,驱动器列表框还有一个Drive属性,用来设置或返回所选择的驱动器名。Drive属性只能用程序代码设置,不能通过属性窗口设置。其格式为:例如:在程序执行期间,驱动器列表框下拉显示系统所拥有的所有可用驱动器名称。在一般情况下,只显示当前的磁盘驱动器名称。如果单击列表框右端向下的箭头,则把计算机所有的驱动器名称全部在下拉列表中显示出来,如图13-15所示。单击某个驱动器名,即可把它变为驱动器列表框对象的当前驱动器。同时还会触发该驱动器列表框对象的Change事件。object.Drive=驱动器字符串Drive1.Drive="c:\"'Drive1是一个驱动器列表框对象的名称2.目录列表框目录列表框用来显示当前驱动器上的目录结构。刚建立时显示当前驱动器的顶层目录和当前目录。顶层目录用一个打开的文件夹表示,当前目录用一个加了阴影的文件夹来表示,当前目录下的子目录用合着的文件夹来表示,如下图所示。

运行时的驱动器列表控件

运行时的目录列表控件目录列表框常用属性是Path,该属性用来设置和返回目录列表框中所显示目录的路径。其语法如下:例如:在目录列表框中,只能显示当前驱动器上的目录。如果要显示其他驱动器上的目录,必须改变路径,即重新设置目录列表框的Path属性。Path属性只能在程序代码中设置,不能在属性窗口中设置。它的功能类似于DOS下的CD命令,用来改变目录路径。对目录列表框来说,当Path属性值改变时,将引发其自身的Change事件。object.Path=路径字符串

字符串变量=object.PathDir1.Path="C:\Windows"'Dir1是一个目录列表框对象的名称PrintDir1.Path例13.7

编制程序,要求程序中有一驱动器列表框对象和一个目录列表框对象,并且实现目录列表框对象和驱动器列表框对象的同步操作。其画面如下图所示。驱动器列表框和目录列表框同步程序向窗体对象上添加上各个控件后,分别将其命名为Drive1(驱动器列表框对象)和Dir1(目录列表框对象),然后添加以下代码:上面代码的作用是,在驱动器列表框对象Drive1发生变化时(如:选择了一个新的硬盘盘符),将目录列表框对象Dir1的Path属性设置为Drive1对象的Drive属性,从而实现两控件的同步操作。即在改变Drive1对象盘符的同时,也改变了目录列表框对象的路径。PrivateSubDrive1_Change()Dir1.Path=Drive1.DriveEndSub13.7.2文件列表框用驱动器列表框和目录列表框可以指定当前驱动器和当前目录,而文件列表框可以用来显示当前目录下的文件(可以通过Path属性改变)。文件列表框的默认控件名是File1。在工具箱中,文件列表框的图标为

。1.文件列表框控件的属性与文件列表框有关的属性较多,介绍如下。(1)Path属性该属用来设置文件列表框中所显示文件所在目录的路径,其作用和目录列表框对象基本相同,用法也相同,主要是用来使其能够和目录列表框对象进行同步操作。(2)Pattern属性Pattern属性用来设置在执行时要显示的某一种类型的文件,它可以在设计阶段用属性窗口设置,也可以通过程序代码设置。在默认情况下,Pattern的属性值为*.*,即所有文件。在设计阶段,建立了文件列表框后,查看属性窗口中的Pattern属性,可以发现其默认值为*.*。如果把它改为*.TXT,则在执行时文件列表框中显示的是*.TXT文件。在程序代码中设置Pattern的格式如下:在窗体上画一个文件列表框,在属性窗口中把它的Pattern属性设置为*.exe,则文件列表框中只显示扩展名为.exe的文件,如图13-18所示。文件列表框对象名.Pattern=属性值文件列表框对象和它的Pattern属性(3)FileName属性FileName属性用来返回在文件列表框中某一被选定的文件名称。(4)ListCount属性ListCount属性可用于组合框,也可用于驱动器列表框、目录列表框及文件列表框。其格式为:这里的“控件”可以是组合框、目录列表框、驱动器列表框或文件列表框。ListCount属性返回控件内所列项目的总数。该属性不能在属性窗口中设置,只能在程序代码中使用。(5)ListIndex属性这里的“控件”可以是组合框、列表框、驱动器列表框、目录列表框或文件列表框,用来设置或返回当前控件上所选择的项目的“索引值”(即下标)。该属性只能在程序代码中使用,不能通过属性窗口设置。在文件列表框中,第一项的索引值为0,第二项为1,依次类推。如果没有选中任何项,则ListIndex属性的值将被设置为-1。控件.ListCount控件.ListIndex[=索引值](6)List属性控件.List(索引)[=字符串表达式]这里的“控件”可以是组合框、列表框、驱动器列表框、目录列表框或文件列表框。在List属性中存有文件列表框中所有项目的数组,可用来设置或返回各种列表框中的某一项目。格式中的“索引”是某种列表框中项目的下标(从0开始)。例如:该例用List属性来输出目录列表框中的所有项目。循环终值Dir1.ListCount指的是目录列表框中的项目总数,而Dir1.List(i)指的是每一个项目。Fori=0ToDir1.ListCountPrintDir1.List(i)Nexti再如:该例用For循环输出文件列表框File1中的所有项目。Fi1e1.ListCount表示列表框中所有文件的总数,File1.List(i)指的是每个文件名。再如:第一个语句用来输出文件列表框中某一被选项目的索引值(下标)。第二个语句显示以该索引值为下标的项目名称。Fori=0ToFile1.ListCountPrintFile1.List(i)NextiPrintFile1.ListIndexPrintFile1.List(File1.ListIndex)2.驱动器列表框目录列表框文件列表框的同步操作在实际应用中,驱动器列表框、目录列表框和文件列表框往往需要同步操作,这可以通过Path属性的改变引发Change事件来实现。例如:该事件过程使窗体上的目录列表框Dir1和文件列表框File1产生同步。因为目录列表框Path属性的改变将产生Change事件,所以在DirLChange事件过程中把Dir1.Path赋给File1.Path,就可以产生同步效果。PrivateSubDir1_change()File1.Path=Dir1.PathEndSub类似地,增加下面的事件过程,就可以使3种列表框同步操作:该过程使驱动器列表框和目录列表框同步,前面的过程使目录列表框和文件列表框同步,从而使3种列表框同步。PrivateSubDrivel_Change()Dir1.Path=Drivel.DriveEndSub13.8文件综合上机练习题学习了关于文件操作的相关知识,让我们一起来编制一个复杂一些的程序。该程序能够实现对一个学生档案数据文件的管理。当然,该程序并不是十分完善,而且在某些操作中或许还存在着一些漏洞,但是编制该程序的目的是为了让读者们自己动手试验一下关于文件操作的编程手段。故希望读者一定要自己动手实验一下。例13.8

设计一个窗体,用于实现学生记录的基本操作,其屏幕设计如右图所示。性别用选项钮,民族用组合框。设计阶段例13.8的窗体界面要求:(1)实现学生记录的翻阅查询。(2)实现学生记录的输入。(3)实现学生记录的修改。(4)在输入和修改时提供可放弃的功能。(5)所有输入的记录要存储在文件中。该窗体中放置了两个图片框(Picture1和Picture2)、一个框架Frame1。这三个控件的作用一样,都是作其他控件的容器来使用。除此之外,还有一个命令按钮Exit。在框架Frame1中放置6个标签(使用Label1控件数组)、4个文本框(其名称为txtNo、txtName、txtKh和txtClass,分别对应学号、姓名、准考证号和班号字段)、2个选项钮(使用optSex控件数组,用于输入性别)和1个组合框(名称为comMz,用于输入民族)。在图片框Picture1中放置7个命令按钮(名称分别为Tp、Prev、Nex、Bott、Add和Upd,分别实现显示第一个记录、上一个记录、下一个记录、最后一个记录、添加一个记录和修改当前记录的功能)。当执行Picture1.Visible=False语句后,其中的所有命令按钮都不可见,当执行Picture1.Visible=True语句后,其中的所有命令按钮都可见。这就是为什么在这里使用图片框的原因。在图片框Picture2中放置2个命令按钮(名称分别为Ok、Cancel,分别实现记录添加、修改和删除操作的确定与取消功能)。同样,当执行Picture2.Visible=False语句后,其中的所有命令按钮都不可见,当执行Picture2.Visible=True语句后,其中的所有命令按钮都可见。在本窗体上设计如下事件过程:'定义类型PrivateTypeStudTypeNoAsIntegerNameAsString*10SexAsBooleanKhAsString*10MzAsString*12ClassAsString*5EndType

DimstudentAsStudTypeDimRecsAsInteger '文件中记录总个数DimCurNoAsInteger '当前记录号DimOpAsInteger ‘操作类型PrivateSubExit_Click()CloseEndEndSub

PrivateSubForm_Load()Picture2.Visible=FalseOpen"student.dat"ForRandomAs#1Len=Len(student)'计算原来文件中的记录个数Recs=LOF(1)/Len(student)IfRecs>0Then '原来文件中有记录时CurNo=1BEnabled(True)DispRecElse'原来文件中无记录时

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论