在DOS操作中,我们所谈及的文件称之为外部文件。外部文件是存储在外部设备上, 如:外存储器上,可由计算机操作系统进行管理,如用dir、type等命令直接对文件进行操作。 Pascal所谈及的文件,称之为内部文件。内部文件的特点是文件的实体(实际文件)也是存储在外存储器上,成为外部文件的一分子,但在使用时必须在程序内部以一定的语句与实际文件联系起来,建立一一对应的关系,用内部文件的逻辑名对实际文件进行操作。内部文件的逻辑名必须符合PASCAL语言标识符的取名规则。 Pascal中的文件主要用于存放大量的数据。如:成绩管理,原始数据很多,使用文件先将其存入磁盘,通过程序读出文件中的数据再进行处理,比不使用文件要来得方便、有效。 Pascal中的一个文件定义为同一类型的元素组成的线性序列。文件中的各个元素按一定顺序排列,可以从头至尾访问每一个元素,从定义上看,文件与数组相似,但它们之间有着明显不同的特征,主要表现在: (1)文件的每一个元素顺序存贮于外部文件设备上(如磁盘上)。因此文件可以在程序进行前由Pascal程序或用文字编辑软件,如edit、ws、Turbo Pascal的edit命令等产生,或在运行过程中由程序产生,且运行完后,依然存贮在外部设备上。 (2)在系统内部,通过文件指针来管理对文件的访问。文件指针是一个保存程序在文件中位置踪迹的计算器,在一固定时刻,程序仅能对文件中的一个元素进行读或写的操作,在向文件写入一个元素或从文件读取一个元素后,相应的文件指针就前进到下一元素位置。而数组是按下标访问。 (3)在文件类型定义中无需规定文件的长度即元素的个数,就是说元素的数据可动态改变,一个文件可以非常之大,包含许许多多元素,也可以没有任何元素,即为一个空文件。而数组的元素个数则是确定的。 使用文件大致有以下几个步骤; (1)说明文件类型,定义文件标识符; (2)建立内部文件与外部文件的联系; (3)打开文件; (4)对文件进行操作; (5)关闭文件。 Turbo Pascal将文件分为三类:文本文件(顺序)、有类型文件(顺序或随机)和无类型文件(顺序或随机)。下面将介绍这些文件及其操作。 一、文本文件 文本文件又称为正文文件或行文文件,可供人们直接阅读,是人机通信的基本数据形式之一。文本文件可用文字编辑程序(如DOS的edit或Turbo Pascal的编辑命令edit)直接建立、阅读和修改, 也可以由PASCAL程序在运行过程中建立。 1、文本文件的定义: 文本文件的类型为TEXT,它是由ASCII字符组成的,是Pascal提供的标准文件之一。标准文件 TEXT已由Pascal说明如下: TYPE TEXT=FILE OF CHAR; 因此,TEXT同标准类型INTEGER、READ等一样可以直接用于变量说明之中,无需再由用户说明。 例如: VAR F1,F2:TEXT; 这里定义了两个文本文件变量F1和F2。 2、文本文件的建立 文本文件的建立有两种方法: (1)直接用Turbo Pascal的Edit建立原始数据文件。 例1 将下表中的数据存入名为A.dat的文件中。 3 4 29 30 50 60 80 90 70 75 60 50 70 45 操作步骤: ①进入Turbo Pascal的编辑状态; ②输入数据; ③存盘,文件名取A.dat。 此时,已将数据存入文本文件A.dat中。文本文件也可用DOS中的Edit等软件建立。 (2)用程序的方式建立中间数据或结果数据文件。 用程序的方式建立文件操作步骤为: ①定义文本文件变量; ②把一外部文件名赋于文本文件变量,使该文本文件与一相应外部文件相关联; 命令格式:ASSIGN(f,name) f为定义的文本文件变量 name为实际文件文件名 如:ASSIGN(F1,`FILEIN.DAT`) 或:ASSIGN(F1,`PAS\FILEIN.RES`) 这样在程序中对文本文件变量F1的操作,也就是对外部实际文件`FILEIN.DAT`或`FILEIN.RES`的操作。上例中文件`FILEIN.DAT`是存贮在当前目录中,而文件`FILEIN.RES`则是存贮在PAS子目录中。 ③打开文本文件,准备写; 命令格式1:REWRITE(f) 功能:创建并打开新文件准备写,若已有同名文件则删除再创建 命令格式2:APPEND(f) 功能:打开已存在的文件并追加 ④对文件进行写操作; 命令格式:WRITE(f,<项目名>) 或:WRITELN(f,<项目名>) 功能:将项目内容写入文件f中 ⑤文件操作完毕后,关闭文件。 命令格式:CLOSE(f) 例2 从键盘上读入表12.1的数据,用程序写入名为B.dat的文件中。3、读取文本文件 文本文件内容读出操作步骤: ①定义文本文件变量; ②用ASSIGN(f,name)命令,将内部文件f与实际文件name联系起来; ③打开文本文件,准备读; 命令格式:READ(f,<变量名表>) READLN(f,<变量名表>) 功能:读文件f中指针指向的数据于变量中 文本文件提供了另外两个命令,在文本的操作中很有用处,它们是: EOLN(f):回送行结束符 EOF(f):回送文件结束符 ⑤文件操作完毕,用CLOSE(f)命令关闭文件。 例3 读出例12.1建立的文本文件,并输出。由于文本文件是以ASCII码的方式存储,故查看文本文件的内容是极为方便,在DOS状态可使用 DOS中TYPE等命令进行查看,在Turbo Pascal中可以象取程序一样取出文件进行查看。 4、文本文件的特点 (1)行结构 文本文件由若干行组成,行与行之间用行结束标记隔开,文件末尾有一个文件结束标记。由于各行长度可能不同,所以无法计算出给定行在文本文件中的确定位置,从而只能顺序地处理文本文件,而且不能对一文本文件同时进行输入和输出。 (2)自动转换功能 文本文件的每一个元素均为字符型,但在将文件元素读入到一个变量(整型,实型或字符串型)中时,Pascal会自动将其转换为与变量相同的数据类型。与此相反在将一个变量写入文本文件时,也会自动转移为字符型。 例4 某学习小组有10人,参加某次测验,考核6门功课, 统计每人的总分及各门的平均分,将原始数据及结果数据放入文本文件中。 分析 (1)利用Turbo Pascal的EDIT建立原始数据文件TESTIN.DAT存贮在磁盘中,其内容如下: 10 6 1 78 89 67 90 98 67 2 90 93 86 84 86 93 3 93 85 78 89 78 98 4 67 89 76 67 98 74 5 83 75 92 78 89 74 6 76 57 89 84 73 71 7 81 93 74 76 78 86 8 68 83 91 83 78 89 9 63 71 83 94 78 95 10 78 99 90 80 86 70 (2)程序读入原始数据文件,求每人的总分及各门的平均分; (3)建立结果数据文件,文件名为TEXTIN.RES. 程序:例5 读入一个行长不定的文本文件。排版,建立一个行长固定为60个字符的文件, 排版要求:(1)当行末不是一个完整单词时,行最后一个字符位用'-'代替, 表示与下一行行头组成完整的单词;(2)第一行行头为两个空格,其余各行行头均不含有空格。 分析 (1)建立原始数据文件。 (2)程序边读入原始数据文件内容,边排版。 (3)每排完一行行长为60字符,并符合题中排版条件,写入目标文件中。 设原始数据TEXTCOPY.DAT文件内容如下: Pavel was arrested. That dat Mother did not light the stove. Evening came and a cold wind was blowing. There was a knock at the window. Then another. Mother was used to such knocks,but this time she gave a little start of joy. Throwing a shawl over her shoulders,she opened the door. 程序:对TEXTCOPY.DAT文本文件运行程序得到排版结果文件TEXTCOPY.RES内容如下: Pavel was arrested.That dat Mother did not light the stov- evening came and a cold wind was blowing.There was a knock at the window.Then another.Mother was used to such knocks,b- ut this time she gave a little start of joy.Throwing a shawl over her shoulders,she opened the door.二、有类型文件 文本文件的元素均为字型符。若要在文件中存贮混合型数据,必须使用有类型文件。 1、有类型文件的定义 有类型文件中的元素可以是混合型的,并以二进制格式存贮,因此有类型文件(除了字符类型文件,因为它实质上是文本文件)不象文本文件那样可以用编辑软件等进行阅读和处理。 有类型文件的类型说明的格式为: 类型标识符=File of 基类型; 其中基类型可以是除了文件类型外的任何类型。例如: FILE1=FILE OF INTEGER; FILE2=FILE OF ARRAY[1--10] OF STRING; FILE3=FILE OF SET OF CHAR; FILE4=FILE OF REAL; FILE5=FILE OF RECORD; NAME:STRING; COURSE:ARRAY[1--10] OF READ; SUN:READ; END; 等等,其中FILE2,FILE3,FILE5中的数组、集合、记录等类型可以先说明再来定义文件变量。 例如: VAR F1:FILE; F2,F3:FILE3; F4:FILE5; 与前面所有类型说明和变量定义一样,文件类型说明和变量定义也可以合并在一起,例如: VAR F1:FILE OF INTEGER; F2,F3:FILE OF SET OF CHAR; F4:FILE OF RECORD NAME:STRING; COURSE:ARRAY[1--10] OF REAL; SUM:READ; END; Turbo Pascal对有类型文件的访问既可以顺序方式也可以用随机方式。 为了能随机访问有类型文件,Turbo Pascal提供如下几个命令: 命令格式1:seek(f,n) 功能:移动当前指针到指定f文件的第n个分量,f为非文本文件,n为长整型 命令格式2:filepos(f) 功能:回送当前文件指针,当前文件指针在文件头时,返回,函数值为长整型 命令格式3:filesize(f) 功能:回送文件长度,如文件空,则返回零,函数值为长整型 2、有类型文件的建立 有类型文件的建立只能通过程序的方式进行,其操作步骤与文本文件程序方式建立的步骤相仿,不同之处:(1)有类型文件的定义与文本文件的定义不同;(2)有类型文件可以利用SEEK命令指定指针随机写入。 3、有类型文件的访问 有类型文件访问的操作步骤与文本文件的程序访问操作步骤相仿,区别之处:(1)有类型文件的定义与文本文件的定义不同;(2)有类型文件可以利用SEEK命令访问文件记录中的任一记录与记录中的任一元素。 例6 建立几个学生的姓名序、座号、六门课程成绩总分的有类型文件。 分析:为简单起见,这里假设已有一文本文件FILEDATA.TXT,其内容如下: 10 li hong 1 89 67 56 98 76 45 wang ming 2 99 87 98 96 95 84 zhang yi hong 3 78 69 68 69 91 81 chang hong 4 81 93 82 93 75 76 lin xing 5 78 65 90 79 89 90 luo ze 6 96 85 76 68 69 91 lin jin jin 7 86 81 72 74 95 96 wang zheng 8 92 84 78 89 75 97 mao ling 9 84 86 92 86 69 89 cheng yi 10 86 94 81 94 86 87 第一个数10表示有10个学生,紧接着是第一个学生的姓名、座号、6科成绩,然后是第二个学生,等等。 从文本文件中读出数据,求出各人的总分,建立有类型文件,设文件名为filedata.fil,文件的类型为记录studreco,见下例程序。 程序:例7 产生数1-16的平方、立方、四次方表存入有类型文件中, 并用顺序的方式访问一遍,用随机方式访问文件中的11和15两数及相应的平方、立方、四次方值。 分析:建立有类型文件文件名为BIAO.FIL,文件的类型为实数型。 (1)产生数1-16及其平方、立方、四次方值,写入BIAO.FIL,并顺序读出输出; (2)用SEEK指针分别指向11和15数所在文件的位置,其位置数分别为10×4和14×4(注意文件的第一个位置是0),读出其值及相应的平方、立方、四次方值输出。 程序:程序运行结果如下:另外,Turbo Pascal还提供了第三种形式文件即无类型文件,无类型文件是低层I/O通道,如果不考虑有类型文件、 文本文件等存在磁盘上字节序列的逻辑解释,则数据的物理存储只不过是一些字节序列。这样它就与内存的物理单元一一对应。无类型文件用128个连续的字节做为一个记录(或分量)进行输入输出操作,数据直接在磁盘文件和变量之间传输,省去了文件缓解区,因此比其它文件少占内存,主要用来直接访问固定长元素的任意磁盘文件。 无类型文件的具体操作在这里就不一一介绍,请参看有关的书籍。三、综合例析 例8 建立城市飞机往返邻接表。文本文件CITY.DAT内容如下: 第一行两个数字N和V; N代表可以被访问的城市数,N是正数<100; V代表下面要列出的直飞航线数,V是正数<100; 接下来N行是一个个城市名,可乘飞机访问这些城市; 接下来V行是每行有两个城市,两城市中间用空格隔开,表示这两个城市具有直通航线。 如:CITY1 CITY2表示乘飞机从CITY1到CITY2或从CITY2到CITY1。 生成文件CITY.RES,由0、1组成的N×N邻接表。 邻接表定义为:分析 (1)用从文本文件city.dat中读入N个城市名存入一些数组CT中; (2)读入V行互通航班城市名,每读一行,查找两城市在CT中的位置L、K,建立邻接关系,lj[l,k]=1和lj[k,j]=1; (3)将生成的邻接表写入文本文件CITY.RES中。 设CITY.DAT内容如下: 10 20 fuzhou beijin shanghai wuhan hongkong tiangjin shenyan nanchan chansa guangzhou fuzhou beijin fuzhou shanghai fuzhou guangzhou beijin shanghai guangzhou beijin wuhan fuzhou shanghai guangzhou hongkong beijin fuzhou hongkong nanchan beijin nanchan tiangjin tiangjin beijin chansa shanghai guangzhou wuhan chansa beijin wuhan beijin shenyan beijin shenyan tiangjin shenyan shanghai shenyan guangzhou 程序:得到CITY.RES文件内容如下: 10 1 fuzhou 2 beijin 3 shanghai 4 wuhan 5 hongkong 6 tiangjin 7 shenyan 8 nanchan 9 chansa 10 guangzhou 0 1 1 1 1 0 0 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0 0 0 例9 对例12.3的FILEDATE.FIL文件内容按总分的高低顺序排序。 分析: 文件的排序就是将文本文件的各分量按一定要求排列使文件有序,文件排序有内排序和外排序二种,内排序是指将文件各分量存入一个数组,再对数组排列,最后将该数组存入原来的文件。外排列不同于内排列,它不是将文件分量存入数组,而是对文件直接排序,内排序比外排序速度要快,但当文件很大时,无法调入内存,此时用外排序法较合适。 本程序使用过程SEEK,实现外排序。 程序:习 题 1、编一程序,计算文本文件中行结束标志的数目。 2、计算文本文件的行长度的平均值、最大值和最小值。 3、一文本文件FILE.DAT存放N个学生某学科成绩,将成绩转换成直方图存入FILE.RES文件中。 如FILE.DAT内容为: 5 78 90 87 73 84 得到直方图文件FILE.RES内容为: 5 ******** ********* ********* ******* ******** 4、银行账目文件含有每一开户的账目细节:开户号、姓名、地址、收支平衡额。写一程序,读入每一开户的账目,生成银行账目文件。 5、通讯录文件每个记录内容为:姓名、住址、单位、邮编、电话,编一程序按姓名顺序建立通讯录文件,要求先建立文件,再对文件按姓名顺序进行外排序。