重定向

本文探讨了文件描述符、输出重定向的基本流程及C库函数如何封装系统调用接口。通过实例代码展示了不同输出函数(如printf、fwrite、write)在重定向后的表现差异,解析了缓存机制对输出的影响,以及fork操作导致的数据复制现象。
摘要由CSDN通过智能技术生成

首先我们先来看一下重定向之输出重定向的基本流程理解。
在这里插入图片描述
我们需要知道我们的文件描述符是什么了?
通过自己理解浅显不深入的说文件描述符是一个进程指向一个文件结构体(file_struct)数组的下标,当然这个下标也是从0开始的,而且默认打开0,1,2对应的都是这个进程关联控制文件的功能。

  • 即分别对应stdin(输入),stdout(输出),stderr(标准错误)。
  • 我们的c库函数只是对这些系统调用接口的封装而已,使用起来更加方便。
  • 我们可以尝试一下close(0),close(1),close(2)简单看一下,默认打开文件描述符的个数变化。
    这里我们close(1)一下,这样就进入了我们输出重定向的话题了。
    来段代码:
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlibh>
int main()
{
	close(1);
	int fd = open("myfile", O_WRONLY | O_CREAT, 00644);
	if (fd < 0)
	{
		perror("open") :
			return 1;
	}
	printf("fd : %d\n", fd);
	fflush(fd);
	close(fd);
	exit(0);
	exit(0);
}


此时发现本应该输出到显示器的内容,输出到文件myfile当中,其中,fd = 1.
在来看一段代码


#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
int mian()
{
	const char * msg0 = "hello printf\n";
	const char *mag1 = "hello fwrite\n";
	const char *msg2 = "hello write\n";
	printf("%s", msg0);
	fwrite(msg1, strlen(msg0), 1, stdout);
	write(1, msg2, strlen(msg2));
	fork();
	return 0;
}
 

运行结果:

hello printf
hello fwrite
hello write

但是当我们对运行中的进程进程进行了重定向close(1),运行结果是这样的:

hello write
hello printf
hello fwrite
hello printf
hello fwrite

我们发现write之调用了一次,其他两个调用了,两次,这个结果可以大胆的用脑壳想一下,肯定是和进程有一定关系的,没错深入思考的确如此。

  • [一般c库文件,调0时候stdin时候是全缓存,而写入显示器是行缓存 ]
  • [库函数自带缓存区,当发生重定向时候,当发生重定向到普通文件时候,数据有以前1(stdout)的行缓存变成了全缓存]
  • [但是我们放入缓存区中的数据,并不会被立马刷新,甚至在子进程之后。]
  • [但是进程退出以后会统一,刷新,写入文件当中]
  • [fork时候会发生一个写时拷贝,所以当父进程刷新的时候子进程也有和父进程相同的数据,随机产生了两份数据]
  • [write没有变换因为write是系统函数,在系统层没有缓存区的存在]
    所以简单的说了:printf fwrite C库函数自带缓存区,系统函数没有。而这个缓存区是对系统调用的一个封装,prinft,fwrite有,系统里面的接口函数没有。所以有C标准库提供。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值