C语言 文件和输入与输出 原理

      如果想持续地保存数据,就必须借助外存设备,如磁盘。程序语言提供访问和使用外存的功能,外存信息存放在操作系统管理下的文件系统里,通过文件和目录的方式来组织的,文件是封装起来的一组数据,目录是子目录和文件的集合。目录或文件可以通过名字来使用。程序在执行中与外存打交道,主要就是访问和使用作为外存信息实体的各种文件。

       程序输入输出的对象可以是各种设备,如键盘、显示器、打印机等,也可以是文件。许多操作系统采用统一的观点,把与输入输出有关的操作都统一到“文件”这一概念,把键盘、显示器等设备也看作文件,给定“文件名”,对它们的操作都通过“文件名”来进行。

       c语言没有专用于输入输出的的语言结构,ANSI C把文件和输入输出功能作为标准库的一部分,以提高程序的可移植性,而且与输入输出有关的机制都统一到文件的概念。标准头文个件<stdio.h>描述了这方面的数据结构和函数。

什么是流?

       文件是输入输出的对象,为与文件交换信息,需要建立与它们的联系,而流就是这种联系,这种建立联系(创建流)的动作被形象地称为打开文件。为从一个文件输入,程序需要创建与该文件关联的输入流,同理要向一个文件输出,就要建立与之关联的输出流。当然还可以建立既能输入又能输出的流。

 标准的流分为两类:字符流和二进制流。所谓字符流把文件看作字符行的序列,每行包含0个或多个字符,最后有换行符’\n’。而二进制流把数据按内存里的形式直接存入文件,二进制流操作保证将数据写入文件后再以同样方式读回,数据的形式和内容都不改变,由于操作不做数据形式转换,在保存和装入大数据时有速度优势,但这种保存形式不适合人的阅读。

流是如何实现的呢?

流通过一种特殊数据结构实现,标准库为此定义了类型FILE

以下是MinGw在库stdio.h中对FILE的结构描述

struct _iobuf {
 
char *_ptr;
 
int _cnt;
 
char *_base;
 
int _flag;
 
int _file;
 
int _charbuf;
 
int _bufsiz;
 
char *_tmpfname;
};

typedef struct _iobuf FILE;

以下是VC在库corecrt_internal_stdio.h中对FILE的结构描述

struct __crt_stdio_stream_data

{

    union

    {

        FILE  _public_file;

        char* _ptr;

    };

   

    char*            _base;

    int              _cnt;

    long             _flags;

    long             _file;

    int              _charbuf;

    int              _bufsiz;

    char*            _tmpfname;

    CRITICAL_SECTION _lock;

};

       这种类型的对象用于保存与流有关的所有信息,实际上这些信息对我们来说是透明的,不必关心。只须关心打开文件的操作返回一个指向FILE的指针,称为文件指针,代表创建的流。对这个流(对应的文件)的操作都是通过这个指针来进行。可以认为这种文件指针就是流的体现, 人们也把文件指针作为流的同义词。

每个c程序启动时自动创建三个流(文件指针):标准输入流(指针名stdin),标准输出流(指针名stdout)和标准错误流(指针名stderr)。

stdin 通常与操作系统的标准输入连接(如:键盘)

stdout通常与操作系统的标准输出连接(如:显示器)

stderr 通常直接连接显示器,不能重定向。

缓冲式输入输出

外存速度较慢, 一般采用成块传递方式, 一次传递一批数据。而程序里使用数据往往不一样,为了弥合程序与外存在数据操作方式和速度方面的差距,人们提出一种技术,即开辟一块存储区(称为数据缓冲区,简称缓冲区),作为文件与使用数据的程序之间的传递媒介。引入缓冲区,主要是提高程序的工作效率。

 输入流操作:文件中的数据以块方式复制到缓冲区,程序需要读数据时就到缓冲区读取,不必每次访问外存,如果要读的数据已经用完,系统会自动从文件取一批数据将缓冲区填满。

输出流操作:每当缓冲区装满后自动执行对文件的成块写操作。

程序打开文件(fopen())后,系统为其分配一个缓冲区(一般为动态存储分配),数据传递都通过缓冲区进行,文件关闭时(fclose())释放缓冲区

对于文件的实操,在一下篇文章中再谈。

猜你喜欢

转载自blog.csdn.net/chinagaobo/article/details/124057535