搜索
您的当前位置:首页正文

如何理解Linux下的文件描述符 ?以及Linux下的重定向与缓冲区这一概念???

来源:哗拓教育


前言

        开始正式内容之前,会先大致描述一下我们在说些什么。所有是内容都是围绕文件描述符这一概念进行展开,但是并不会直接切入这一概念,因为这一概念并不是很难,但是因为文件描述符而涉及的周边概念是很广泛的,我会由周边涉及到的知识逐步递进,逐渐引入文件描述符。

首先我们先解答下面的疑问。

1.文件是什么?

请参考 ,总结一下就是,文件 = 内容 + 属性(属性也是数据)

2.文件的相关操作是什么?

无外乎两种:a.对内容的操作 b.对属性的操作

3.访问文件本质是谁在访问?

进程。为什么?

用户访问文件,会先写代码 ---> 编译  ---> 形成可执行程序  ---> 运行 ---> 通过接口进行访问,而运行起来的程序不就是进程嘛。

文件存储在哪里?磁盘(磁盘是硬件),用户可以直接向硬件进行写入嘛?答案是肯定不可以的,只有操作系统才有权限向硬件进行写入。

如果普通用户也想向硬件中进行写入呢?比如说我们就想直接修改磁盘上的文件,怎么办???此时,就需要操作系统提供文件类的系统调用接口了。

要注意,这样的接口只有一套,因为系统只有一个。什么意思呢?Linux关于文件类的系统接口只有一套,但是C/C++/Java/Python...都有各自关于文件类的接口,为什么它们不直接使用系统接口呢?

一是因为系统接口比较难:语言上对这一套系统接口进行封装,可以让用户更好的使用。也就导致了不同的语言,有不同的语言级别的文件访问接口(都不一样),但是,底层都是一样的。
 

二是因为跨平台:如果语言不提供对文件的系统接口的封装,那么所有的访问文件的操作,都必须直接使用系统的接口,而使用语言的用户访问文件一旦使用系统接口,编写所谓的文件代码,那么就无法在其他平台中直接运行!
 

4.为什么有Linux下一切皆文件这一说法?

感性的认识:

文件:可以read , write

显示器: printf 、 cout -->  也可以理解为是一种 write

键盘 :scanf、cin ---> 也可以理解为是一种  read

站在程序的角度,读取/写入的数据需要加载至内存(input)

站在内存的角度,需要向文件/显示器写入/读取这些数据(output)

普通文件 ---> fopen/fread  ---> 进程的内部(内存 )---> fwrite  ---> 文件内部  (前面的部分是input,后面的部分是output)

那么什么叫做文件呢?

站在系统的角度,能够被input读取,或者能够output写出的设备就叫做文件!
狭义文件:普通的磁盘文件
广义上的文件:显示器,键盘,网卡,声卡,显卡,磁盘,几乎所有的外设,都可以称之为文件
结论就是所有的硬件也都是可以被看作成文件,都是可读可写的,但是在实现的时候,键盘〈只能读,不能写)显示器(只能写,不能读)
 

那么经过上面的铺垫,欢迎阅读下面的内容。

        注意,下面内容很长很长,涉及面很宽泛,欢迎恰饭。


关于C语言的文件接口与Linux下系统文件接口

C语言的文件接口

a.什么叫做当前路径???

当一个进程运行起来的时候,每一个进程都会记录自己当前所处的工作路径
 

示例1:

"w" :打开一个文件进行写入,如果不存在该文件,创建之

示例:

其实想说明的是,无论我是哪个路径,运行上述的程序,如果该文件不存在,那么就会在当前路径下创建该文件。问题是,系统是如何得知当前路径的???

Windows(Vs)下,一般源文件和可执行程序是不在一个路径的,编译链接的时候,会生成一个debug文件夹,可执行程序是放在这个文件夹的

 Linux下当前路径是根据可执行程序在改变(有些不准确)

Linux下,进程在从上往下运行的时候,当没有看到这个文件,就会去调用系统接口,进行创建


        所以我们能解释这个问题:为什么在当前路径运行可执行程序,形成的临时文件就在当前路径,在上级路径运行可执行程序,形成的临时文件就在上级路径 。 因为:进程运行也在这个路径,所以创建的临时文件当然也在这个路径 

小结①(上述所讲的是关于“当前路径”这一个知识点)


示例:

输出:

那么,问题来了,请问往文件中写入字符串的时候要不要加上'\0’(C语言中字符串结束标志是'\0',这里'\n'只是一个普通字符)

这里要不要加1?答案是不需要。因为'\0'是C语言的规定,文件不需要遵守。文件存储是在磁盘,属于系统的管理范围,不属于语言的范畴
 

恶补一个小知识点:可以利用 > 重定向来清空文件

因为C语言规定,w写入,会先清空文件再进行写入

> :重定向,先打开文件,然后清空文件,再进行重定向

>:可以理解为是一条指令,底层是C语言“w”形式实现的


示例:

小结②(上述所讲的是a.关于C语言文件操作是不需要考虑'\0'的,因为'\0'不属于系统的规定; b.利用 > 重定向可以清理文件)


函数:

  • fopen
FILE *fopen( const char *filename, const char *mode );
  • fwrite
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
  • fgets

char *fgets( char *string, int n, FILE *stream );
  • fprintf
int fprintf( FILE *stream, const char *format [, argument ]...);

示例:

输出:

小结③(上述所讲的是实现一个简单的 "cat" 指令)


Linux下系统文件接口

其实C语言接口也是封装的系统接口,对应情况如下:

感觉是不是很像,但是用法嘛,系统接口还是有点难以学习的,因为C语言接口可以直接使用,系统接口需要一定的知识储备量。

  • open
NAME
       open, creat - open and possibly create a file or device  //打开或创建一个文件

SYNOPSIS
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>

       int open(co

因篇幅问题不能全部显示,请点此查看更多更全内容

Top