p27 文件

p27文件

一、 文件的概念

如以前学过的inputoutput,它们是Pascal的标准文,分别对应着计算机的标准输入设备(一般为键盘)和标准输出设备(一般为显示器),在Pascal中可以直接使用,甚至省略不写,这样的文件实际上是与外设直接打交道,因此我们把它称作“外设文件”。

在程序设计中,常常需要从键盘输入若干输入数据,当数据量相当大时很麻烦、也很容易出错;同时,在程序运行后也往往会产生大量的数据(结果),这给验证结果的正确性和测试程序的对错带来了很大的麻烦。能不能有一种方法,让程序自动从某个地方读取数据运行,再将程序的运行结果保存到指定的地方呢?当然可以,这就是Pascal的“文件”类型。这里的文件是指存储在外部存储设备(如磁盘)上、可由计算机识别的一系列数据成分组成的整体。也就是我们平时所说的“磁盘文件或内部文件”。

二、 文件的概念及特点

Pascal中,文件被定义为同类型的元素组成的顺序集合。文件所含元素的个数,称为文件的长度。长度为0的文件,即不含任何一个元素的文件,称为空文件。

从定义上看,文件与数组很相似,但它们有明显的不同。数组的长度是固定的,而文件的长度不固定,而且可以很长;数组可通过下标对任一数组元素进行访问,而文件一般必须从前往后逐个进行访问,直到找完为止;数组可以整体赋值,而文件却不可以。

文件具有以下3个特点:

1)顺序性

文件是由同一类型的元素组成的,它们是按一定的顺序排列和存放的,一般读取文件 中的数据或输出文件的内容,都必须从文件头到文件尾顺序访问。在Pascal中定义的每个文件类型变量,都自动附带一个文件指针,通过文件指针指向文件中的某个元素,并对该元素进行操作。

2)永久性

前面讲过的所有数据类型如数组、记录、集合等,它们都是在程序运行时在内存空间临时开辟和存储的,所以不具备永外性;而文件是存储在磁盘等外部存储介质上的,因而它们可以永久地存储起来。并且数据以文件形式存放后,还可以被其他程序调用,成为共享数据。

3)容量大

由于内存容量很有限,所以我们在定义和使用数组等数据类型时,数据存储容量往往受到很大的限制;而文件是存储在磁盘等外存中,因而容量可以很大、甚至是无限的。

由于文件有如上特点,文件类型的变量成为一种特殊的变量。文件类型的变量的值可以在程序执行前存在,也可以在程序执行后存在,而且它的值可以比程序本身还大。文件变量是指对文件整体的内容,并且其内容是存放在外存中。对文件的操作只能是对文件中的每个元素进行操作,即由文件指针来对文件的元素进行操作。

三、 文件的分类

Pascal中,按文件的结构形式分,文件可以为文本文件、类型文件和无类型文件。

文本文件又称为text文件、正文文件,文件的内容是以字符形式(ASCII码)存放的,因此可以用DOS中的TYPE命令显示其内容。

类型文件又称为file文件、二进制文件,它的内容是以二进制的代码的形式存放的。

无类型文件是一个低层的I/O通道,主要用来直接访问固定长度的元素的任意磁盘文件,而不管文件的类型和构造,在信息学奥赛中不会用到这种类型的文件,所以后面也不再介绍了。

如果按照文件的存取方式分,文件可分为顺序存取文件和随机存取文件两种,即顺序文件和随机文件。

顺序文件的读写都要从文件头开始顺次进行,而随机文件可以从文件的任意指定位置进行读写。

Pascal中,文本文件属于顺序存取文件,而类型文件属于随机存取文件。

顺序文件具有如下几个特征:

(1) 当程序开始把数据输出(写)到文件中去时,总是从文件的起始位置开始,也就是说不可能从文件的中间位置开始存放数据;

(2) 输出的数据是一个接一个地存放在文件中的;

(3) 当程序从文件中输入(读取)数据到内存时,也总是从文件的起始位置开始。也就是说不可能从文件的中间位置开始读取数据;

(4) 读数据时,也必须按存入文件时的顺序一个接一个的读入到内存中;

(5) 对同一个文件的读写操作不能交叉进行。即不能在读取文件的同时往文件里写,也不能在写入文件的同时从文件里读。

四、 文件处理的标准过程和函数

Pascal提供了一批用于文件操作的预定义标准过程和函数,它们在文件的操作过程中非常有用。

1. 适合于所有文件类型的标准过程和函数

名字

过程或函数

基本功能

assign

过程

将一个外部文件名赋予文件变量。

close

过程

关闭一个已打开的文件。

eof

函数

返回文件结束状态。

erase

过程

删除一个外部文件。

rename

过程

重新命名一个外部文件名。

reset

过程

打开一个已存在的文件。

rewrite

过程

建立并打开一个新文件。

2.只适合于文本文件的标准过程和函数

名字

过程或函数

基本功能

append

过程

打开一个已存在的文件,从尾部增添元素。

eoln

函数

返回文件的行结束状态。

read

过程

从文本文件中读取一个或多个值赋予相应的变量。

readln

过程

执行read过程,然后跳到文件的下一行。

write

过程

将一个或多个值 写入文本文件。

writeln

过程

执行write过程,然后写入一个行结束标志。

3.只适合于类型文件的标准过程和函数

名字

过程或函数

基本功能

read

过程

从类型文件中读取一个或多个值赋予相应的变量。

write

过程

将一个或多个值写入类型文件中。

filepos

函数

返回指定文件的当前文件位置。

filesize

函数

返回文件的当前长度,即文件中元素的个数。

seek

过程

将文件指针移到指定的位置。

五、文件操作的一般步骤

Pascal中,不管使用哪种类型的文件,必须按照以下步骤操作,当然,不同类型的文件操作的具体语句和格式可能略有不同。

1.在使用文件前,必须对文件类型和变量进行说明;

2.把磁盘上的实际文件(外部文件)和Pascal程序当中的文件(内部文件)建立关联;

3.打开文件,将文件指针指向开始位置,为文件读写作准备;

4.对文件进行读、写操作;

5.在使用完文件后,一定要记住关闭文件,确保文件的完整性和可靠性,否则会引起文件处理错误。

六、文本文件的操作步步骤

在初学Pascal语言编制程序时,我们就和文本文件打交道了,只是Pascal系统隐含安排了有关的操作,从而方便了我们的使用。当时我们不知道,也没有必要知道而已。例如:

program aa(output);

var x,y:integer;

begin

  x:=5;y:=x*x;

  writeln(‘x=’,x,’y=’,y)

end.

程序运行后,屏幕显示为:x=5y=25

实际上,程序在运行时,是把数据输出到一个名为output的文本文件中去,系统预先定义了output文件具有text类型,而且指定显示器的文件就是output。在程序中执行到write语句时,就把内容输出到显示器上,因此我们从显示器上就可以直接看到结果了。

文本文件的结构虽是ASCII字符序列,但它与一般以字符为元素的文件不同,它的文件是按行排列的,行与行之间用行结束标记隔开,最后则有一个文件结束标记。它对字符的处理,一般是以行为单位进行读、写操作的。由于每行的长度不一样,因此采用顺序文件的处理办法。

文本文件的操作步骤如下:

1)文本文件的变量在使用前必须说明其类型为text 

由于文本文件是标准文件,Pascal系统已经预定义了,其形式如下:

type text=file of char;

因此,text是系统保留字,就表示文本文件类型。所以,用户在使用时无需再定义text类型,就可以直接引用text,如:

var f1,f2,f3:text;

(2)使用文本文件前,要先调用assign过程,把外部文件名赋予文本文件变量。

assign过程的调用格式如下:assign(filevar,filename);

其中,filevar是文件变量,要在变量说明部分预先定义;filename是合法的文件名的字符串表达式。assign过程的作用就是把filename赋给文件变量filevar,在程序中对文件变量filevar的操作即为对磁盘文件filename的操作。如:

assign(f1,’input1.txt’);

注意,input1.txt是实际的文件名,默认位置在Pascal安装目录下,也可以用文件的绝对路径。如:assign(f2,’a:\test1\input1.txt’);也可以通过read语句读入filename(这儿的filename是字符串类型的变量),将文件变量与用户所输入的文件名相联系,如:

read(filename);

assign(f3,filename);

(3)当将数据写入(输出)到文件时,应先调用rewriteappend过程打开该文件,再用writewriteln将实际数据写入到该文件中。

rewrite过程的调用格式如下:rewrite(filevar);

它的作用是创建一个新的磁盘文件,并以写的方式打开该文件,初始化文件为空,文件针指向开始位置。在调用rewrite过程前必须先调用assign过程,给文件变量一个实在的文件名。

append过程的调用格式如下:append(filevar);

append过程的作用与rewrite相似,只是用append打开的文件只能向文件尾部添加数据而已。

write过程的调用格式如下 :write(filevar,var1,var2,...,varn);

它的作用是向文件filevar中写入变量var1,var2...,varn的值,当然,文件的元素类型必须和变量类型一致,每向文件中写入一个数据,文件指针向下移一个位置。

writeln过程的调用格式如下:writeln(filevar,var1,var2...,varn);

它的作用是执行write过程,然后再写入一行结束标志。

4)当需要从文件中读取数据(输入)到内存时,应先调用reset过程打开该文件,再用readreadln将数据读入到内存变量中,且只能从文件的开头读数据。

reset过程的调用格式如下:reset(filevar);

它的作用是打开一个已存在的磁盘文件,并将文件指针指向开始位置,表示可以开始读取文件了,但不能向文件写数据,同样filevar文件名必须存在,且文件中必须有满足程序运行要求的输入数据。

read过程的调用格式如下:read(filevar,var1,var2,...,varn);

它的作用是执行read过程,然后跳到文件的下一行。

5)对文件的输入、输出操作必须以行为单位进行,读写完毕要用close命令关闭文件。

close过程的作用是关闭一个文件,无论是向磁盘写文件,还是从磁盘文件中读取数据,读、写完毕后都必须用close命令关闭已打开的文件,以保证文件的完整性和可靠性,否则将可能引起文件处理错误。

close过程的调用格式如下:close(filevar);

除了上述几个重要的过程外,在文本文件的使用过程中还经常用到两个重要的函数。

eoln函数:行结束函数,函数值为布尔型,当文件指针指向回车换行符时,函数值为真(true),否则为假(false)eoln函数一般用在从一个已打开的文件中读取数据时判断一行的数据是否读完。如果文件是以写状态打开的,则eoln函数的值总是假。eoln函数的调用形式为eoln(filevar)

eof函数:文件结束函数,函数值为布尔型,当文件指针指向文件结束标志(ctrl+z)时,函数值为真(true),否则为假(false)eof函数一般用在从一个已打开的文件中读取数据时判断文件是否结束。eof函数的调用形式为:eof(filevar).

七、文本文件的应用举例

1、从键盘输入一段正文,将它复制到指定的磁盘文件中,然后再在显示器上输出。

问题分析:

1)从键盘输入正文,需逐个输入字符,且按行存储,每行用回车键结束;

2)当文件写结束时,加一个文件结束标志(ctrl+z),再用close关闭文件;

3)打开此文件,逐个读取字符,并显示在屏幕上。

程序代码如下:

program aa(input,output);

var ch:char;

str1:string[15];

file1:text;

begin

  write(‘please input a file name:’);

  readln(str1);           {输入文件名、建立文件}

  assign(file1,str1);        {将内部变量名与外部文件建立关联}

  rewrite(file1);           {以写状态打开该文件,准备写入}

  while not eof do          {文件未结束(即未从键盘输入ctrl+z)就写一行}

begin

  whle not eoln do      {一行未结束(即未从键盘输入一个回车换行符)就继续写}

    begin

      read(ch);        {从键盘读入一个字符给ch}

      write(file1,ch);    {ch写入文件中}

     end;

   readln;              {键盘上换一行}

   writeln(file1);         {写一个行结束符到文件中}

end;

  close(file1);                 {写文件结束,关闭文件}

  writeln;                    {屏幕换行}

  reset(file1)                  {以读状态再次打开该文件}

  while not eof(file1) do         {从文件读取数据,直到遇到文件结束符为止}

begin

  while not eoln(file1) do     {读取一行数据}

     begin

       read(file1,ch);        {从文件中读一个字符给ch}

       write(ch:3);          {ch输出到屏幕上}

     end;

   readln;                  {遇到回车换行符就换一行继续}

   writeln;                  {屏幕换行}

 end;

   close(file1);                  {读文件结束,关闭文件}

 end.

2、将文本文件f复制到文本文件g中。

程序代码如下:

program aa(input,output);

var f,g:text;

ch:char;

begin

  assign(f,’input.txt’);

  assign(g,’output.txt’);

  reset(f);rewrite(g);

  while not eof(f) do

     begin

      while not eoln(f) do

         begin

           read(f,ch);write(g,ch);

         end;

       readln(f);writeln(g);

     end;

   close(f);close(g);

end.

3设有文本文件g,其中的数据如下(□表示空格)

1□2□3

4□5□6□7

8□9

10□11□12

……

试分析下面程序的执行结果。

program aa(input,output);

var g:text;

sum1,sum2,i,j,k:integer;

begin

  assign(g,’input.txt’);

  reset(g);

  sum1:=0;

  for i:=1 to 3 do

begin

  while not eoln(g) do

    begin

      read(g,j);

      sum1:=sum1+j

    end;

  readln(g)

end;

  reset(g);

  sum2:=0;

  for i:=1 to 3 do

begin

  for k:=1 to 3 do

     begin

       read(g,j);

       sum2:=sum2+j

     end;

   readln(g);

 end;

   writeln(sum1:6,sum2:6);

   close(g);

 end.

程序的运行结果为:45 48

posted @ 2010-10-11 20:52  lj_cherish  阅读(348)  评论(0)    收藏  举报