进程描述符:task
文件描述符:就是数组下标值
int open(char* path,int falg);
返回值:返回最小且未被占用的文件描述符下标(文件描述符)
1、在应用层,一般打开文件时,返回为3
因为每个应用层的程序打时,都不可缺少键盘/屏幕/错误输出,所以init进程在运行进程时,都会为你打开"键盘/屏幕/错误输出"三个文件(一切设备皆文件)
2、上述函数将文件描述符引用计数+1
dup函数
复制文件描述符:
1、int dup(int oldfd)
作用:将oldfd文件描述符复制一份放置在最小未被使用的文件描述符中。
2、 int dup2(int oldfd, int newfd);
作用:复制文件描述符,可以用参数newfd指定新的文件描述符值。
情况讨论:
1、若参数newfd已经被程序使用,则系统会将newfd先关闭掉,
2、若参数newfd=oldfd,则直接返回oldfd
dup2函数本质
int dup2(int newfd,int oldfd)
{
if(newfd==oldfd)
return oldfd;
//关闭fd
close(oldfd);
return dup(newfd,oldfd);
}
PS:上述函数将文件描述符引用计数+1
文件的关闭:
close(int fd);
当多个文件描述符指向同一个文件时,需要关闭所有的文件描述符,只有将打开的引用计数成为0时,系统内核才会释放该空间。
close(fd)只是将引用计数-1.
io重定向:
通过dup和close改变输入输出流方向
int fd=open
将1号文件描述符(默认设置为屏幕输出,也就是说所有标准输出函数输出内容都是通过1号文件描述符输出内容的),关闭1号描述符(本进制的1号文件描述符为未被占用),dup/open文件,返回的文件描述符就为1
系统默认
0是键盘
1是屏幕
2是错误输出
所以创建文件的描述符一般从3开始
代码实现
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
void main(int argc,char* argv[])
{
//fd=3.0键盘1屏幕2错误输出
int fd=open("./a.txt",O_WRONLY|O_CREAT|O_TRUNC,0664);
printf("fd=%d\n",fd);
//dup函数将指定的文件描述符复制下来
int nfd=dup(fd);
printf("%d\n",nfd);
write(nfd,"abc",3);//abc
write(fd,"123",3);//abc123
//打开的是同一个文件,文件“光标”到3,继续写入
close(fd);
close(nfd);
}
close(1);//fd=1关闭屏幕
int fd=open("./a.txt",O_WRONLY|O_CREAT|O_TRUNC,0664);
// write(fd,"hello",5);
printf("%d\n",fd);
fflush(stdout);
close(fd);
int sfd=dup(1);
close(1);
int fd=open("./a.txt",O_WRONLY|O_CREAT|O_TRUNC,0664);
printf("test");
puts("abcd");
close(sfd);
dup(sfd);
printf("hello\n");