Linux—基础IO—详解1

x33g5p2x  于2021-09-24 转载在 Linux  
字(2.4k)|赞(0)|评价(0)|浏览(497)

1. 回顾C语言的文件操作接口

C语言文件接口(库函数):fopen/fclose/fread/fwrite/fseek

  • fopen函数
FILE *fopen(const char *path,const char *mode);

解释:path:带路径的文件名称(待打开的文件)
mode:
r:以可读方式打开,不可写。文件不存在,则报错。
r+:以读写方式打开。文件不存在,则报错。
w:以可写方式打开,不可读。文件不存在,则创建。文件存在,则截断(清空文件内容)文件。
w+:以读写方式打开,文件不存在,则创建,文件存在则截断(清空文件内容)文件。
a:追加写,不可读。在文件末尾进行追加,文件不存在则创建文件。文件存在,则在文件末尾开始写。
a+:可读追加写,在文件末尾进行追加写,文件不存在则创建文件,文件存在,则在文件末尾开始写。
返回值:文件流指针 FILE

  • fclose: 关闭文件流指针
int fclose(FILE *fp);
  • fread函数
size_t fread(void *ptr,size_t size,size_t nmemb,FILE* stream);

解释:ptr:要将读到的保存到哪里去,ptr 保存用户准备的一个空间(缓冲区)的地址
size:块的大小,单位是字节
nmemb:块的个数 eg:size=2 nmemb=5 ----->10
常见用法:size=1,nmemb可以指定任意块,读到的字节数量也就可以用nmemb表示
stream:文件流指针,表示要从哪里开始读;
返回值:返回的是独到的块的个数

  • fwrite函数
size_t fwrite(const void *ptr,size_t size,size_t nmemb,FILE* stream);

解释:ptr:要写入文件中的内容
size:块的大小,单位字节
nmemb:块的个数 总写入字节数量=块的大小/*块的的个数
stream:文件流指针
返回值:写入块的个数

  • fseek函数
int fseek(FILE* stream,long offset,int whence);

解释:stream:文件流指针
offset:偏移量,单位字节。相对于whence而言的偏移量
whence:SEEK_SET :文件的头部
SEEK_SUR:当前文件流指针的位置
SEEK_END:文件的尾部
函数使用范例:

2. 系统调用文件的接口

系统调用文件接口:open/read/close/write/lseek

  • open函数
int open(const char *pathname,int flags);

解释:pathname:待要打开的文件
flags:O_RDONLY :只读方式 O_WRONLY:只写方式 O_RDWR:读写方式
以上三个常量,必须指定一个且只能指定一个
O_CREAT:文件不存在则打开,需要告知权限,使用8进制数字表示
O_TRUNC:截断文件(清空文件)
O_APPEND:追加
以上常量还可以进行组合使用,组合方式为按位或 eg:O_WRONLY || O_CREAT || O_TRUNC
返回值:返回一个整数,含义为文件描述符

  • close
close(int fd);
  • read函数
ssize_t read(int fd,void *buf,size_t count);

解释:fd:文件描述符
buf:将读到的内容放到这个buf这个缓冲区当中
count:表示最大能够都多少个字节,和buf的大小有关系,需要在buf当中预留一个\0的位置
返回值:>0:读到的字节数量
-1:都失败了

  • write函数
ssize_t write(int fd,const void *buf,size_t count);

解释:fd:文件描述符
buf:写到文件里的内容
count:写入的字节数量
返回值:>0:表示写入文件真实的字节数量
-1:写入失败了

  • lseek函数
off_t lseek(int fd,off_t offset,int whence);

解释:fd:文件描述符
offset:偏移量
whence:SEEK_SET、SEEK_CUR、SEEK_END
函数使用范例:

3. 文件描述符

Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0,标准输出1,标准错误2.
*
0,1,2对应的物理设备一般是:键盘、显示器、显示器。
*
查看当前正在运行文件描述符的方法:ll /proc/pid/fd

文件描述符就是从0开始的小整数。当我们打开文件时,操作系统在内存中要创建相应的数据结构出来描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而系统执行open系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针/*files,指向一张表files_struct,该表最重要的部分就是包含一个指针数组,每个元素都是一个指向打开文件的指针!所以,本质上,文件描述符就是该数组的下标。所以,只要拿着文件描述符,就可以找到对应的文件。
*
文件描述符的分配规则:最小为占用原则
*
一个进程最大可以打开多少个文件描述符呢?
其实这个是自己可以修改的:可以通过ulimit -n [大小]

4. 文件流指针&文件描述符和文件流指针的关系

  1. 文件流指针
    FILE:

FILE文件流指针是一个typedef之后的值,本质上是一个结构体
“/usr/include/stdio.h“

struct _IO_FILE{…}

进程终止的时候说的刷新缓存区:指的是C库当中维护的读写缓冲区;
解释:_exit()函数之所以不会刷新缓冲区,是因为,_exit()函数是内核代码,直接操作内核结束了进程,而此时并不会通知上层C库,所以,C库维护的缓冲区完全在无感知的情况下进程就终止了;

  1. 文件流指针和文件描述符的区别?
  • 文件流指针是一个结构体,在结构体内部保存了文件描述符
  • 文件描述符是一个正整数,其含义为fd_array数组的下标
  • 文件流指针维护了读写缓冲区

相关文章