您的位置:首页 > 运维架构 > Linux

linux文件基础之标准IO

2016-06-28 19:28 387 查看

unix文件基础

6/28/2016 6:00:39 PM

输入输出

文件描述符:

顺序分配,非负整数;

内核用来表示一个特定进程正在访问的文件;

其他资源(socket,pipe)的访问标识;

stdin\stdout\stderr

默认shell打开,分别对应0\1\2

他们都是系统自动打开的文件指针类型FILE*;不用手动的fopen/fclose

不用缓存的IO (系统调用)

通过文件描述符访问fd(File Description)

open()/read()/write()/lseek()/close()

标准IO**(c库函数)**

通过FILE* 访问

printf()/fprintf()/fopen()/fwrite()/fread()/fseek()/fclose()/fgets()

文件指针FILE*:每个被使用的文件都在内存开辟一个区域保存文件的相关信息,这些信息都保存在一个结构体类型的变量中,这个结构体类型由系统定义为FILE;

: 所有的I/O操作只是简单的从程序中移进和移出,这种字节流就是

文本流:流中处理数据以字符出现
'\n'---回车符
CR/换行符LF的ASCII
例如:数字 2016 在文本流中: '2' '0' '1' '6'
对应的ASCII:       50  48  49  54
--------------------------------------------
二进制流: 流中处理的是二进制序列。
如流中有字符,则用一个字节的二进制ASCII码表示;
如果是数字,用对应的二进制数表示;
'\n'不进行替换
例如:数字 2016 在二进制流中: 0111 1110 0000


文件缓冲:

缓冲文件系统(上层磁盘IO)

目的: 减少系统调用read/write,增加系统的效率。

定义:系统自动在内存中为每个正在使用的文件开辟一个缓冲区,程序从内存中向磁盘输出的数据必须现在缓冲区中存放,待缓冲区装满(1k/4k),再将其一起放到磁盘中,从而减少read/write等的系统级调用,从而提高效率。

文件流的缓存形式分类:

行缓存:    1024B = 1K
全缓存:    4096B = 4K
无缓存:    stderr

刷新缓存:fflash(FILE*): 强行刷新一个流


非缓冲文件系统(底层磁盘IO)

定义依靠os,通过os对文件进行读写,直接面向底层的磁盘。

文件的基本操作

fopen();其实没什么强调的,注意打开时的mode:

FILE* fopen(const char* filename, const char* mode)
r:      打开只读文件,必须存在
r+:     打开可读写文件,必须存在
w:      打开只写,没有则创建
w+:     打开读写,没有则创建
a:      追加方式打开只写文件,无则创建
a+:     追加方式打开读写,无则创建
b:      以二进制方式打开


fclose();关闭已经打开的流.

int fclose(FILE*);
成功返回0
失败返回EOF,并设置errno


关闭文件之前,刷新缓存,释放缓存。

进程正常终止时,所有未写的缓存数据的流被刷新,所有打开的流关闭;

调用关闭函数fclose()后,再调用fclose(),后果未知。

读写流

文件打开后,可以使用不同的非格式化IO中选择读写方式:

fgetc/fputc:每次读/写一个字符

fgets/fputs:每次读/写一行,每行都以 ‘\n’ 终止。

fgets读入的一行,包括’\n’;

使用fgets时,须指定缓存的长度n

当读入的不超过n-1,则将其送入缓存,并以NULL结尾;

当读入的一行超过了n-1,则只返回一个不完整的行,而缓存还是以NULL结尾,下一次调用fgets时,将继续读未读完的行。

使用fputs():将一个以NULL结尾的字符串写到指定的流,但是NULL不写出;

fgets()/fputs()遇到NULL字节就停止,而在结构体中的指针可能就是NULL,因此在读写结构体时,不能使用fgets()/fputs(),而更愿意使用fwrite()/fread();

在使用fgets()/fputs()时,需要自己在每行终止处添加一个换行符’\n’

fread/fwrite:直接I/O,每次读写是,每个对象都具有指定的长度,常用于从二进制文件中读写一个结构体,以解决fgets()/fputs()遇到NULL就结束的尴尬。

判断读写流是否结束

feof(FILEE*);判断文件是否结束。(可用于二进制文件)

EOF文件结束的返回标志。

定位流

int fseek(FILE* stream, long offset, int whence); //设定流的文件位置
long ftell(FILE* stream);  //取得当前的文件位置,返回long型
void rewind();//    将流的位置为文件开始
rewind() <===> (void) fseek(stream, 0L, SEEK_SET);


其中,fseek()函数的whence参数:

SEEK_SET:设置offset位置为文件开始的位置

SEEK_CUR:设置offset位置为文件当前的位置

SEEK_END:设置offset位置为文件结束的位置

出错处理

全局错误码errno: “errno.h”,全局可见。

errno不会被置为0

输入错误信息:

strerror()- 映射errno对应的错误信息;

perror()-输出用户信息和errno对应的错误信息,负责解析错误代码信息

note

gets():不推荐使用,因为调用者在使用gets()时,不能指定缓存的大小,因此在某行的长度>缓存大小时,可能造成缓存越界,将数据写到缓存后的空间,后果不堪设想。

gets()与fgets()区别: gets()不会将’\n’存入缓存。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  标准IO linux