七.系统调用及文件操作
一. 用man查看函数类型
man open//open(2)
man fopen//fopne(3)
- 2.系统调用
- 3.库函数
strlen()不需要切换到内核态是库函数。
printf()->write库函数,调用write()函数进行系统调用,需要内核支持。
fopen->open,调用了系统调用。
二. 文件类型
windows中有文本文件和二进制文件。
linux不分文件类别,都是二进制文件。
每个文件有自己的属性信息,struct inode进行存储,存储的大小,名称,位置等。
三. 文件操作
-
open()打开文件,打开方式,打开文件名,返回值为文件描述符。
open()会产生一个这个文件的文件结构表struct file,存储的打开方式,引用计数,文件偏移量,文件的inode值,通过这个值来找文件。
int fd=open("文件名",打开方式,权限);
-
O_WRONLY,只写方式打开。
-
O_CREAT,如果没有这个文件,则创建这个文件。
-
O_REONLY,只读方式打开。
- close()关闭文件,参数为文件描述符。
- read()读取文件,文件描述符,读取到哪,读取多少,返回值为读取的字符个数,如果为0则代表字符读到文件末尾。
int n=read(文件描述符,存入的位置,存入的大小);
- write()写文件,文件描述符,写入的内容,写入多少。
write(文件描述符,写入的内容,写入的大小);
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
int main(){
int fd=open("file.txt",O_WRONLY|O_CREAT,0600);
if(fd==-1){
printf("open failed\n");
exit(1);
}
write(fd,"hello",5);
close(fd);
exit(0);
}
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
int main(){
int fd=open("file.txt",O_RDONLY);
if(fd==-1){
printf("open failed\n");
exit(1);
}
char buff[128]={0};
int n=read(fd,buff,127);
printf("read(%d)=%s\n",n,buff);
close(fd);
}
四. 文件表
文件表为对应打开的文件和其文件描述符的表,一般情况下最大同时打开1024个文件,每个程序有每个程序的文件表。
文件描述符为文件的序号,从0开始,在linux中键盘和屏幕也为文件,占文件描述的前三个。
0 stdin //键盘,标准输入
1 stdout //屏幕,标准输出
2 stderr//屏幕,标准错误输出
3 file.txt//文件
五. 父子进程与文件操作
- 父进程已经打开的文件子进程也算打开。
- 父进程与子进程共享文件偏移量。
- 父进程与子进程都关闭文件后才算关闭,只有一个关闭另一个可以继续使用。
- fork()之后父子进程新开的文件没有关系。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
int main(){
int fd=open("file.txt",O_RDONLY);
if(fd==-1){
exit(1);
}
pid_t pid=fork();
if(pid==-1)exit(1);
if(pid==0){
char buff[32]={0};
read(fd,buff,1);
printf("child buff=%s\n",buff);
sleep(1);
read(fd,buff,1);
printf("child buff=%s\n",buff);
}else{
char buff[32]={0};
read(fd,buff,1);
printf("child buff=%s\n",buff);
sleep(1);
read(fd,buff,1);
printf("child buff=%s\n",buff);
}
close(fd);
eixt(0);
}
//abcd
六. 练习实现bash的cv程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
int main(int argc,char *[]argv,char *[]envp){
if(argc !=3){
printf("参数出错");
exit(1);
}
int fd1=open(argv[1],O_RDONLY);
if(fd1==-1){
printf("文件打开错误");
exit(2);
}
int fd2=open(argv[2],O_WRONLY|O_CREAT,0600);
if(fd2==-1){
printf("文件打开错误");
exit(3);
}
int n=1;
char buff[1024]={0};
while((n=read(fd2,buff,1024))>0) {
write(fd1,buff,n);
}
close(fd1);
close(fd2);
exit(0);
}