Mask -- 标记,掩盖//掩码
Mode & ~umask 110 110 110
0666 000 000 010(~umask)
0002(umask) 111 111 101(umask)
=110 110 100
系统调用:
1.打开
需要包含头文件 #include <fcntl.h>
int open(const char *pathname, int flags);
open("1.c",O_WRONLY|O_CREAT,0666 );
int open(const char *pathname, int flags,int mode);
功能:
获得一个文件描述符
参数:
pathname:文件名
flags:
必须项:他们之间是互斥的,所以有且只能有一个
O_RDONLY
O_WRONLY
O_RDWR
可选项:
O_CREAT, 创建文件 //这个标志量存在,则需要指定参数 mode
O_EXCL, 需要和O_CREAT同时使用,表示新建的文件不存在,成功,否则open就会失败
O_TRUNC 文件内容清空
O_APPEND追加
fopen()
r ---- O_RDONLY
r+ O_RDWR
w O_WRONLY|O_TRUNC|O_CREAT ,0666
w+ O_RDWR|O_TRUNC|O_CREAT ,0666
a O_WRONLY|O_APPEND|O_CREAT ,0666
a+ O_RDWR|O_APPEND|O_CREAT ,0666
2.读写
需要加头文件 <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
功能:通过文件描述符fd读取文件中的数据
参数:fd:文件描述符
buf:存放数据空间的首地址
count:要读到数据的字节个数
返回值:
成功返回 读到的数据字节个数
失败返回 -1
读到文件结尾返回 0
ssize_t write(int fd, const void *buf, size_t count);
功能:读取 buf 里的数据 写入 文件描述符 fd中
参数:fd:文件描述符
buf:要写入的数据的空间首地址
count:要写入的数据字节个数
返回值
成功 返回 写入的数据字节个数
失败 返回 -1
写到buf结尾 返回 0
3.定位:
off_t lseek(int fd, off_t offset, int whence);
功能:定位读写的位置
参数:fd:文件描述符
offset:偏移量
whence:SEEK_SET:文件开始
SEEK_CUR:当前位置
SEEK_END:文件末尾
返回值:成功 返回 偏移量
失败 返回 -1
off_t len = lseek(fd,0,SEEK_END);
//返回值就是文件大小
创建空洞文件:
先偏移 写操作
注意:1.不支持O_APPEND的追加模式,无法生成空洞文件
2.lseek函数执行失败,文件指针还在偏移前的位置
3.lseek函数在设备文件上偏移无效
4.fifo不支持偏移
面试题:
文件IO的文件描述符最大值是多少 ==》1024
练习:
模拟云盘下载,实现拷贝
思路:
- 打开-open
- src dest
- 创建空洞文件
- 先获取源文件的大小
- 创建同样大小的一个目标空洞文件
- 读写 拷贝
- read / write
- 关闭文件
- close
3.关闭 close
int fileno(FILE *stream);
可以将stream 转化为 文件描述符
FILE *fdopen(int fd, const char *mode);
可以使用 文件描述符 打开文件 返回一个 流指针
fdopen 打开的 mode 必须 包含 之前fd打开的模式,否则会报错 打开失败
文件IO 用于底层设备相关的开发
标准IO 纯上层开发,应用程序开发,优先选择标准IO
库函数:优点:a.方便 功能更多 b.可移植性好
不足:c可能存在 安全性 隐患(程序可能被植入病毒)
系统调用:
优点:安全 可控
目录IO
1.打开目录
DIR *opendir(const char *name);
功能:打开目录
参数:name:目录名
返回值:成功 返回可用的目录流
失败 返回NULL,并设置error
2.读写目录
readdir需要包含头文件<dirent.h>
struct dirent *readdir(DIR *dirp);
功能:读取一个目录(读目录下文件的属性,包括文件名,inode号,文件类型)
参数:drip :要读取的目录流指针 =》DIR 类型的 指针
返回值:成功 返回 读取到的 struct dirent 指针->指向结构首地址,结尾返回NULL
失败 返回 NULL指针,并设置error
3.关闭目录
int closedir(DIR *dirp);
功能:关闭一个打开的目录。
参数:@dirp 要关闭的目录流
返回值:成功 返回0
失败 返回-1,并设置error
获取文件属性
int stat(const char *path, struct stat *buf);
功能:获得文件属性
参数:@path 指定文件路径
@buf 保存属性信息内存区域首地址,传参需定义变量,传首地址
返回值:成功 返回0
失败 返回-1,并设置error
练习:打印当前目录下的所有文件
硬链接和软连接
硬链接:本质:是给我们的文件取别名。
与源文件直接关联。修改一个,另一个同时被修改。删除一个另一个不会有影响。
Linux系统中规定,只有在文件的打开次数为0(即文件这个时候没有打开),并且文件的硬连接数为0,此时文件才会被删除
特点:
(1)不占用硬盘空间
(2)不能对目录操作
(3)不能跨文件系统
命令:ln 源文件名 硬链接文件名
我们新建的硬链接文件,只是给源文件起了一个别名,他们共用同一个inode号。
软连接:类似于我们windows的快捷方式,用来记录我们目标的路径
特点:
(1)占用磁盘空间
(2)可以对目录操作
(3)可以跨文件系统
命令:ln -s 源文件 软链接文件
可以发现我们新建的hello2.c实质是我们hell1.c的快捷方式。并且他们的inode号不一样。
原理图
int stat(const char *pathname, struct stat *statbuf);
功能:获取文件属性
参数: @path 指定文件路径
@buf 保存属性信息内存区域首地址,传参需要定义变量,传首地址
返回值:成功 返回 0
失败 返回 -1 并设置error
所属者信息获得
struct passwd *getpwuid(uid_t uid);
传参文件的uid 例:st.st_uid;
返回一个struct passwd 类型的结构体,里面成员是文件所属者的信息
所属组
struct group *getgrgid(gid_t gid);
参数:传参所属组gid 例:st.st_gid
功能:返回一个 struct group 类型的结构体 里面成员是所属组的信息