目录
1.内核提供的文件系统调用
1.1open和close
通过[man]指令浏览其描述,这里截取片段。
第一个open是文件存在的情况下打开文件,第一个参数为文件名,若不指定文件路径,则默认为父进程的工作路径。第二个参数为标记位,int类型的每个比特位的0 和 1代表了不同的标记。Linux提供了多种标记。
第二个open是文件不存在的情况下打开文件,第三个参数为文件创建的初始权限。
close即关闭文件。
下面给出代码实例以供参考:
umask(0); //将umask置0
int fd = open("log.txt",O_WRONLY | O_CREAT | O_TRUNC,0666); //相当于C语言的fopen的"w",只写、自动创建、自动覆盖
//文件的权限受umask的影响
close(fd);
下面列举一些常用的标记:
- O_WRONLY ->只写
- O_CREAT ->创建
- O_TRUNC ->覆盖
- O_RDONLY ->只读
- O_APPEND ->追加
需要多个标记组合在一起时,使用 '|'(按位或运算符) 连接即可。
1.2标记位
int类型有4个字节,32个比特位,每一个比特位的0 和 1代表了不同的标记。例如有:......0001与......0010就是两个不同的标记。我们使用代码实例来演示:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define ONE (1<<0)
#define TOW (1<<1)
#define THREE (1<<2)
#define FOUR (1<<3)
void select(int flags)
{
if(flags & ONE) printf("one\n");
if(flags & TOW) printf("tow\n");
if(flags & THREE) printf("three\n");
if(flags & FOUR) printf("four\n");
}
int main()
{
select(ONE);
select(ONE | TOW);
select(ONE | TOW | THREE);
select(ONE | TOW | THREE | FOUR);
return 0;
}
也就是说,Linux提供的标记实质上是一个宏,每一个宏代表了不同的信号。
1.3write和read
write是一个系统调用,其声明为([man]指令查看):
需要注意的是,write()是从文件的起始位置开始写的,如果在open()中没有O_TRUNC或者O_APPEND标记,那么为将文件以前的内容的一部分覆盖掉。也就是说,要想像C语言一样自动清空文件的内的数据必须加上O_TRUNC标记 。
下面给出write的实际使用案例以供参考:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
umask(0); //将umask置0
int fd = open("log.txt",O_WRONLY | O_CREAT | O_TRUNC,0666); //相当于C语言的fopen的"w",只写、自动创建、自动覆盖
if(fd < 0) return 1;
char* msg = "hello Linux\n";
write(fd,msg,strlen(msg)); //像fd描述的文件写入msg指向的字符串
close(fd);
return 0;
}
编译运行,查看生成的"log.txt"文件:
read也是一个系统调用,其声明为([man]指令查看):
这里以上面write生成的文件给出read的实际使用案例以供参考:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
int fd = open("log.txt",O_RDONLY);
char buffer[64];
read(fd,buffer,sizeof(buffer)-1); //留一个位置补'\0'
buffer[strlen(buffer)]=0; //文件的字符串不以'\0'结尾
printf("%s",buffer);
close(fd);
return 0;
}
2.文件描述
2.1文件描述符
进程可以打开多个文件,所以操作系统会有大量的文件。操作系统为了管理被打开的文件,使用了"先描述,再组织"的方法将被打开的文件描述为一个struct file的内核结构体,其包含了文件的大部分属性,多个内核结构体之前以特定的数据结构组织起来。
这些struct file结构体并不是文件描述符,而是操作系统为了管理被打开的文件而创建的。事实上,文件操作研究的是进程和被打开文件的关系,也就是说文件是被进程打开的。那么进程和struct file结构体中间还有一层结构体,名为struct files_st