操作系统的底层系统调用
open()
打开一个文件read()
从文件中读取数据write()
向文件中写入数据close()
关闭文件
我们首先打开帮助手册来看一下这些方法
我们写一段代码,来创建写入文件
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<fcntl.h>
int main()
{
int fd = open("file.txt",O_WRONLY|O_CREAT,0600);
//我们首先创建一个文件,全新创建需要给出权限
//fd是一个文件描述符,用于来唯一标识我们的文件
assert(fd!=-1);
printf("fd = %d\n",fd);
write(fd,"hello",5);//写入字符
close(fd);
exit(0);
}
我们在写一段代码,用来打开文件,读文件
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<fcntl.h>
int main()
{
int fd = open("file.txt",O_RDONLY);
//打开文件,不用给权限
assert(fd != -1);
char buff[128] = {0};
int n = read(fd,buff,127);
//将读入的数据存入buff,然后输出buff
printf("n = %d,buff = %s\n",n,buff);
close(fd);
}
我们可以通过读和写来复制一个文件,怎么做呢?我们先打开一个二进制文件,在创建一个新的文件,并且去读二进制文件将读到的数据写入新文件中,重复这个过程知道读不到数据的时候就复制完成(当read()
返回值为0,即读不到数据)
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<fcntl.h>
int main()
{
int fdr = open("/home/zyq/Linux/file/main",O_RDONLY);
//只读方式打开
int fdw = open("/home/zyq/Linux/file/main2",O_WRONLY|O_CREAT,0600);
//创建新的文件,O_CREAT 给权限
if(fdr == -1 ||fdw == -1)//表示原文件打开或新文件创建出现错误
{
exit(0);
}
char buff[256] = {0};
int num = 0;//代表读到多少数据
while((num = read(fdr,buff,256))>0)
{
write(fdw,buff,num);
}
close(fdr);
close(fdw);
父子进程共享打开的文件
文件描述符就是文件表的下标,当我们打开一个文件file.txt,就会创建一个struct file的结构体在内核来表明这个打开的文件,inode节点会存放一些文件的属性信息继而来寻找到file.txt文件
我们写一段代码来进行测试
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<fcntl.h>
/*
*复制pcb(文件表数组)的同时
*指向同一个 struct file 共享文件偏移量 inode
*打开(open)的文件描述符后 fork 公用一个文件描述符
*先fork 后打开open 文件不共享同一个文件描述符
*
* */
int main()
{
int fd = open("file.txt",O_RDONLY);
assert(fd!=-1);
pid_t pid = fork();
assert(pid!=-1);
if(pid == 0)
{
char buff[128] = {0};
int n = read(fd,buff,1);
printf("child : %s\n",buff);
sleep(1);
n = read(fd,buff,1);
printf("child : %s\n",buff);
}
else
{
char buff[128] = {0};
int n = read(fd,buff,1);
printf("parent : %s\n",buff);
sleep(1);
n = read(fd,buff,1);
printf("parent : %s\n",buff);
}
close(fd);
}
复制进程并没有读出重复的东西,继而是父子进程共享文件偏移量
进程复制后,子进程会复制得来父进程的文件表,都指向同一个结构体,结构体中的引用计数变成2,父子进程来读的时候文件偏移量移动继而造成不会重复读一个同一个数据
- 复制pcb(文件表数组)的同时
- 指向同一个 struct file 共享文件偏移量 inode
- 打开(open)的文件描述符后 fork 公用一个文件描述符
- 先fork 后打开open 文件不共享同一个文件描述符