dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

实现文件共享操作

代码演示:
dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

这样两个文件描述符就共享这个文件可以共同操作。
执行结果为:
dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

我们可以看到在执行完成之后也没有出现内容覆盖的现象。

不会出现数据覆盖的说明

文件描述符表
dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

使用dup、dup2复制方式实现文件共享时,不管复制出多少个文件描述符,它们永远只有一个文件表,使用同一个V节点,所以永远不会覆盖。所有文件描述符共享同一个文件位移量去操作文件时,不管复制了多少个文件描述符,不管谁操作后文件位移量都会被更新,因此不会出现覆盖。

实现重定位

重定位

某文件描述符原来指向了A文件,输出数据是输出到A文件,但是重定位后,文件描述符指向了B文件,输出时数据输出到了B文件,这就是重定位。

所谓重定位,说白了就是,文件描述符所指向的文件该变了,使得数据输出的目标文件也随之变。

使用dup、dup2实现重定位

回顾printf与write的关系:
dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

printf输出时,原本通过1,将数据输出到标准输出文件(显示器)的,但是现在,我想让printf输出到file.txt文件,而不是输出到屏幕,应该怎么办?
最简单的办法是就是,把printf函数调用的write函数里面的1,改成指向file.txt文件的新描述符即可,但是不幸的是
write中的1写死了,1这个数字改不了,怎么办?
1这个数改不了,但是可以对1进行重定位,让1不再指向标准输出文件,而是指向file.txt,printf的数据,就输出到了file.txt文件中。

实现printf函数输出到文件而不是屏幕

(a)open file.txt文件,返回一个文件描述符,比如3
dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

close(1),不要再让1指向标准输出文件(/dev/stdout)

使用dup、dup2把3复制到1上,让1也指向file.txt文件

dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

1这个文件描述符就被重定位了,凡是通过1输出的数据,都被写到了file.txt中,printf底层调用的是write(1, …),用的也是1,printf的数据就被输出到了file.txt中。
相当于printf函数的输出目的地,被重定位为了新的文件,这就是重定位。

代码演示:
dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

上面的代码在关闭文件描述符1之后对于printf进行调用打印,结果为:
dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)
我们可以看到关闭文件描述符为1的文件之后,printf函数没有办法将数据打印到屏幕上。

dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)
执行结果为:

dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

上面代码我们没有指定赋值之后的新的文件描述符,因为当1关闭之后后面需要复制新的文件描述符的时候文件描述池中最小的没有被使用的就是文件描述符1。并且printf里面的内容都被写到文件里面,因为文件描述符1被关闭之后被复制到了文件描述符3上面,这时文件描述符1和文件描述符3都指向了dup.txt文件,所以printf的内容都被输入到文件描述符3所操作的dup.txt文件。

实现scanf函数从文件读取数据而不从键盘

dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)
执行结果为:
我们输出并打印从文件输入到程序的数据:
dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

函数中的文件描述符值写死了,无法修改为新的描述符,但是你又希望该函数,把数据输出到其它文件中,此时就可以使用dup、dup2对该函数中的文件描述符,进行重定位,指向新的文件,函数就会将数据输出到这个新文件。

重定位命令 >

重定位 命令(>)是dup、dup2的典型应用,这个命令在重定位时,就是调用dup、dup2函数来实现的。
使用的例子:
ls > file.txt
ls的结果原本是输出到显示器的,但是>从定位后,就输出到了file.txt文件。

我们使用一下:
dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

>命令过程分析

(a)>命令(程序)会open打开file.txt文件,假设返回的文件描述符是3

dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

(b)ls命令(程序)原本会调用write(1, …),将结果输出到标准输出文件(显示器),但是 >会调用dup2,把3复制到1上,实现重定位,让1也指向file.txt文件,ls的结果自然就输出到file.txt文件了。
dup、dup2复制的意义,实现文件共享操作,实现重定位,重定位命令 >【linux】(l)

所以>命令就完成实现。