一、系统调用
什么是系统调用:
由操作系统实现并提供给外部应用程序的编程接口。(Application Programming Interface, API)。是应用程序同系统之间数据交互的桥梁。
C标准函数和系统函数调用关系。一个helloworld如何打印到屏幕。
C标准库文件IO函数
fopen、fclose、fseek、fgets、fputs、fread、fwrite……
r 只读、r+读写
w 只写并截断为0、w+读写并截断为0
a 追加只写、a+追加读写
二、文件IO
1.open/close 函数
函数原型
manpage 第二卷,open函数如下
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
返回一个文件描述符,理解为整数,出错返回-1
pathname 文件路径
flags 权限控制,只读,只写,读写。
常用参数
O_RDONLY、O_WRONLY、O_RDWR
O_APPEND、O_CREAT、O_EXCL、O_TRUNC、O_NONBLOCK
第二个open
多了一个mode参数,用来指定文件的权限,数字设定法
文件权限 = mode & ~umask
open常见错误:
1.打开文件不存在
2.以写方式打开读文件(权限问题)
3.以只写方式打开目录
当open出错时,程序会自动设置errno,可以通过strerror(errno)来查看报错数字的含义
以打开不存在的文件为例:
执行该代码,结果如下:
open函数:
int open(cahr *pathname, int flags) #include <unistd.h>
参数:
pathname:欲打开的文件路径名
flags:文件打开方式: #include <fcntl.h>
O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_APPEND |
O_TRUNC | O_EXCL | O_NONBLOCK……
返回值:
成功:打开文件所得到对应的文件描述符(整数)
失败:-1,设置errno
int open(char *pathname, int flags, mode_t mode)
参数:
pathname:欲打开的文件路径名
flags:文件打开方式: O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_APPEND |
O_TRUNC | O_EXCL | O_NONBLOCK……
mode:参数3使用的前提,参2指定了O_CREAT。取值8进制,用来描述文件的访问权限(rwx 0644)
创建文件最终权限 = mode & ~umask
返回值:
成功:打开文件所得到对应的文件描述符(整数)
失败:-1,设置errno
close 函数:
int close(int fd);
参数:
fd:要关闭文件的文件描述符
返回值:
成功:返回0
失败:-1,设置errno
其他相关知识
PCB进程控制块
文件描述符
结构体PCB的成员变量file_struct* file 指向文件描述符表。
从应用程序使用角度,该指针可理解记忆成一个字符指针数组,下标0/1/2/3/4……找到文件结构体。
本质是一个键值对0、1、2……都分别对应具体地址。但键值对使用的特性是自动映射 ,我们只操作键不直接使用值。
新打开文件返回文件描述符表中未使用的最小文件描述符。
STDIN_FILENO 0
STDOUT_FILENO 1
STDERR_FILENO 2
最大打开文件数
一个进程默认打开文件的个数是1024.
命令查看ulimit -a查看open files 对应值。默认1024
可以使用ulimit -n 4096 修改
当然也可以通过修改系统配置文件永久修改该值,但是不建议这样操作。
cat /proc/sys/fs/file-max可以查看该电脑最大可以打开的文件个数。受内存大小影响。
FILE结构体
主要包含文件描述符、文件读写位置、IO缓冲区三部分内容。
struct file{
……
文件的偏移量;
文件的访问权限;
文件的打开标志;
文件内核缓冲区的首地址;
struct operations * f_op;
……
}
查看方法:
1)/usr/src/linux-headers-3.16.0-30/include/linux/fs.h
2)lxr:百度 lxr --> lxr.oss.org.cn ---> 选择内核版本 --> 点击File Search 进行搜索
-->关键字:“include/linux/fs.h” --> Ctrl+F 查找 “struct file{”
-->得到文件内核中结构体定义
-->“struct file_operations”文件内容操作函数指针
-->“struct inode_operations”文件属性操作函数指针
2.read/write函数
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
read函数:
ssize_t read(int fd, void *buf, size_t count);
参数&