Linux:基础IO接口的解析


理解库函数和系统调用

  • 上面的 fopen fclose fread fwrite 都是C标准库当中的函数,我们称之为库函数(libc)。
  • 而, open close read write lseek 都属于系统提供的接口,称之为系统调用接口

我们先看下面一张图:

在这里插入图片描述

由图可以看出:库函数是对系统调用接口的一种封装

库函数IO接口

fopen / fread / fwrite / fseek / fclose — FILE*

fopen

FILE *fopen(char *filename, char *mode);(文件名称,打开方式)

打开方式:

  • r 只读
  • r+ 读写
  • w 只写
  • w+读写
  • a 追加写
  • a+ 追加读写
  • b 二进制操作

追加写:每次写入数据总是写入到文件末尾

注意:

  1. r+的读写和w+的读写有什么区别??
  • r+读写打开文件,若文件不存在则报错;
  • w+读写打开文件,若不存在则创建,若存在清空原有内容(w/w+每次都会清空文件原有内容后写入数据)
  1. a 不仅仅是追加写,若文件不存在还会创建新文件

  2. b 默认清空如果不指定b,则认为文件是文本操作,加上b则认为是二进制操作
    区别在于有一个特殊字符,只是一个字符,但占据两个字节的内存(读取100个字节大小的文件,文本操作最终读取出来的数据,不一定是100个字节)

  3. 返回值: 返回一个FILE*的文件留置针作为文件的操作句柄;失败返回NULL

fread、fwrite

size_t fread(char *buf, size_t block_size, size_t block_count, FILE* fp);(缓冲区,块大小,块个数,文件流指针)
size_t fwrite(char *data, size_t block_size, size_t block_count, FILE* fp);(数据首地址,块大小,块个数,文件流指针)

注意:

  • bread/fwrite操作的数据实际大小是 块大小*块个数 ; 块大小=10, 块个数=2;意味着要写入/读取20个字节的数据
  • 返回值:返回实际操作的块个数 例如:独取一个文件size =10; count = 2;
    如果文件大小足够则返回2 / 但是若文件大小只有16字节,组会返回1,因为第二块没有读满
  • fread 如果读到了文件末尾会返回0;若读取1000个字节,数据块个数(count)为1, 数据块大小(size)只有512字节, 虽然读了512字节也会返回0

fread / fwrite比较推荐数据块大小为1, 数据块个数是想要操作的数据长度

对文件数据进行字符串操作的时候要注意文件数据中的\0这种数据

fseek

int fseek(FILE *fp, long offset, int whence);(将文件的读写指针从whence位置偏移offset个字节) — 跳转文件读写位置

fseek 跳转读写位置

  • SEEK_SET 从文件起始位置偏移
  • SEEK_CUR 从文件当前读写位置偏移
  • SEEK_END 从文件末尾偏移

fseek:文件没有数据也可以跳转读写位置

fclose

int fclose(FILE *fp); 关闭文件流指针,释放资源

系统调用IO接口

open/read/write/lseek/close

open

int open(char * filename, int flag, mode_t mode);
  • filename:要打开的文件名称

  • flags:选项参数 (文件的打开方式 )
    必选项:
    O_RDONIY / O_WRONLY / O_RDWR 只读/只写/可读可写 (三种只能选择其一)

    可选项:

    • O_CREAT 文件不存在则创建新文件,存在则打开
    • O_EXCL 跟 O_CREAT同时使用,文件不存在则创建,存在则报错
    • O_TRUNC 打开文件的同时清空原有内容
    • O_APPEND 追加写,总是将数据写入到文件末尾

使用O_CREAT就一定要通过open函数的第三个参数指定文件的创建权限

  • mode:权限 - -若使用了O_CREAT有可能创建新文件,就一定要指定文件权限,八进制数字(mode—权限0664 给定&~umask)

  • 返回值: 一个非负整数(文件描述符 )

write

ssize_t write(int fd, char *buf,size_t count);
  • fd:open返回的文件描述符(文件操作句柄)

  • buf:要写入文件的数据的空间首地址

  • count:要写入的数据大小

  • 返回值:返回实际写入文件的数据字节长度;失败返回-1

read

ssize_t read(int fd, char *buf,size_t len);
  • fd:open返回的文件描述符

  • buf:从文件中读取数据放到缓冲区中的首地址

  • len:想要读取的数据长度,注意len不能大于缓冲区的大小

  • 返回值:返回实际写入文件的数据字节长度;失败返回-1

lseek

off_t lseek(int fd, off_t offset, int whence);
  • fd:open返回的文件描述符

  • offset:偏移量

  • whence:从哪里开始偏移

    • SEEK_SET 从文件起始位置
    • SEEK_CUR 从文件当前读写位置
    • SEEK_END 从文件末尾
  • 返回值:成功返回当前位置相对于起始位置的偏移量;失败返回-1
    在这里插入图片描述

close

int close(int fd); 通过文件描述符关闭文件,释放资源

如果对这些函数的解析不充分的话可以使用 man 手册


如有不同见解,欢迎留言讨论~~

猜你喜欢

转载自blog.csdn.net/AngelDg/article/details/106780276