本文章由公号【开发小鸽】发布!欢迎关注!!!
老规矩–妹妹镇楼:
一. 系统api与库函数的关系
(一)调用库函数的流程
当我们使用一些库函数,如printf(“hello world”)时,调用了文件指针 FILE *stdout, 该文件指针的组成为:
fd 文件描述符
f_pos 位置
buffer 8k的缓冲区
如,调用printf(“hello\n”)后,系统会调用write(1, “hello\n”, 6),接着进入内核调用sys_write(“hello\n”),再通过设备驱动显示在显示器中。
(二)内核中的管理
内核中有虚拟文件系统,内存管理,进程管理,设备管理,PCB进程控制块,文件描述符表。
文件描述符表中存的就是文件指针中的文件描述符,如描述符0对应的是FILE * stdin,1对应的是 FILE *stdout,2对应的是 FILE * stderr,因此,上面调用printf(“hello\n”),系统会自动调用write(1, “hello\n”, 6)中的1指的就是FILE *stdout,写到标准输出上。
二. 文件IO
(一) open函数
通过查看man文档的第二页来了解open函数:man 2 open。该函数用来打开文件。
1. 函数原型
int open(const char *pathname, int flags);
int open(const char *pathname, int flags);
2. 函数参数
(1)pathname
文件名
(2)flags:
必选项:
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:读写
可选项:
O_APPEND:追加
O_CREATE ; 创建文件
O_NONBLOCK:非阻塞
3. 函数的返回值
成功时返回最小的可用文件描述符,失败时返回-1.设置errno。
(二) close函数
1. 用途
关闭一个文件描述符
2. 函数原型
int close(int fd);
3. 函数返回值
成功时返回0,错误时返回-1、设置errno。
(三) read
读取文件
1. 函数原型
size_t read(int fd, void* buf, size_t count);
2. 函数参数
fd : 文件描述符
buf: 缓冲区
count :缓冲区大小
3. 函数返回值
成功时返回读到的大小
失败时返回-1,并设置errno
返回0表示读到了文件末尾
(四) write
向文件中写入。
1. 函数原型
size_t write(int fd, const void* buf, size_t count);
2. 函数参数
fd: 文件描述符
buf: 缓冲区
count: 缓冲区大小
3. 函数返回值
成功时返回写入的字节数
失败时返回-1,并设置errno
返回0代表未写入
(五) lseek
移动文件的读写位置。
1. 函数原型
off_t lseek(int fd, off_t offset, int whence);
2. 函数参数
fd: 文件描述符
offset: 偏移量
whence:
SEEK_SET: 文件开始位置
SEEK_CUR: 当前位置
SEEK_END: 文件的结尾
3. 函数返回值
成功时返回当前位置到开始的长度
失败时返回-1.并设置errno
4. 函数的作用
移动文件读写位置
计算文件大小
5. lseek实现计算文件大小
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/stat.h
#include<fcntl.h>
int main(int argc, char *argv[]){
if(argc != 2){
printf(“./a.out filename\n”);
return -1;
}
int fd = open(argv[1], 0_RDONLY);
int ret = lseek(fd, 0, SEEK_END);
printf(“file size is %d\n”, ret);
close(fd);
return 0;
}