文件描述符

一、文件常见的几种打开与读写方式:

FILE *fopen(const char *path, const char *mode);//它是库函数  打开文件
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);//读入数据 
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);//fwrite写入数据
ssize_t write(int fd, const void *buf, size_t count);//write写入数据

#include <stdio.h>

extern FILE *stdin;//标准输入
extern FILE *stdout;//标准输出
extern FILE *stderr;//标准错误

pcb.c

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<string.h>
  4 int main()
  5 {
  6     printf("pid: %d,ppid: %d,uid: %d,euid: %d ,gid: \%d, egid: %d\n"\  7             ,getpid(),getppid(),getuid(),geteuid(),getgid(),getegid());
  8 FILE*fp=fopen("./log","w");
  9 if(NULL==fp){
 10     perror("fopen");
 11     return 1;
 12 }
 13 const char*str="hello,bit!!!\n";
 14 int i=0;
 15 while(i<10){
 16 fwrite(str,strlen(str),1,fp); //linux下一切皆文件,‘\0’不写入文件里,所以不用加1                                                                                    
 17    i++;
 18 }
 19 fclose(fp);
 20     return 0;
 21 }

makefile

.PHONY:clean
pcb:pcb.o
    gcc -g $^ -o $@
%.o:%.c
    gcc -c -g $< -o $@
clean:
    rm -f *.o main

运行结果:

这里写图片描述

把内容写进了log文件中并进行了清空

普通用户可以往log里写内容么?

这里写图片描述

怎样解决呢?

这里写图片描述
几个标识符的名称:
这里写图片描述

一个整数最少能传32个标识符 每一个宏占一个比特位

二、文件描述符fd

文件描述符就是一个小整数。默认的3个缺省打开的文件描述符
0:标准输入 键盘
1:标准输出 显示器
2:标准错误 显示器

文件描述符的应用:

 14     printf("fd:%d\n",fd);
 15     int fd1=open("./mylog1",O_WRONLY|O_CREAT,0644);
 16     int fd2=open("./mylog2",O_WRONLY|O_CREAT,0644);
 17     printf("fd1:%d\n",fd1);
 18     printf("fd2:%d\n",fd2);

这里写图片描述
这里写图片描述

文件描述符就是从0开始的小整数。(0-7)

打开文件:

1)file结构体:描述目标文件的结构体(表示一个已经打开的文件对象)
2)让进程和文件关联起来:(进程执行open系统调用)
3)每个进程都有一个指针*files,指向一张表files_struct(包含一个指针数组,每个元素都是一个指向打开文件的指针)本质上,文件描述符就是该数组的下标。所以,只要拿着文件描述符,就可以找到对应的文件。

close(0);
close(2);

这里写图片描述
结论;
文件描述符的分配规则
从当前的最小的未被分配的文件描述符给你

进程和文件之间的对应关系:

这里写图片描述
所谓的文件描述符就叫做数组下标

close1

这里写图片描述
FILE里面有一个结构体,里面存在文件描述符

文件指针和文件描述符的区别:

  • 文件指针是指针,文件描述符是一个整数
  • 文件指针是c语言结构层识别的,文件描述符是系统调用层识别的。
  • 文件指针里存在一个结构体,里面存在与之对应的文件描述符。

重定向的原理:

将对应的数组里的内容做个改变。
输出重定向:先把1关闭,再打开文件。
输入重定向:先把0关闭,再打开文件。
追加重定向:
这里写图片描述

这里写图片描述

为什么FILE结构体中会存在文件描述符?

这里写图片描述

系统调用及文件调用

这里写图片描述

分析:
发现库函数多打印了

为什么printf多打了2次?

fork之前调用完了。当往显示器里写没问题,往文件里写就有问题了*,与写入的类型文件无关;

如果代码无fork,是单进程,会不会与出现这种问题?

不会,因为它只有一个执行流

总结:原因:

文件的写入问题。在fork之前文件已经被写入了文件里,就不可能出现大量打印的问题。(当调用fork时,printf和fwrite里的数据并没有被写入到文件里。)
1)全缓冲问题
2)写时拷贝问题

缓冲方式:

行缓冲:如果这条语句写完包含‘\n’,并刷新到屏幕上
全缓冲:写入数据全写在缓冲区里,知道缓冲区满或进程退出才会刷新到目标文件之中。

  • printf的调用是父进程调用的fork父子进程发生写时拷贝,分别调用printf,所以打两次
  • write只打一次说明它没有缓冲区,fwrite底层调用write,说明缓冲区是c库提供的

FILE文件里包含的内容:

  • 文件描述符
  • 行缓冲
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值