主要介绍:
什么是“流”,“流”的基本概念,“流”对于内存和外部设备着什么样的作用,C语言默认打开的三个“流”:stdin、stdout、stderr👀。
通过《C语言》文件这一章的学习,我们学会了如何向文件进行读写操作,也就是如何让数据从内存中保存到硬盘上,或是如何从硬盘上读取数据放到内存中。硬盘其实是一个外部设备,那有人就要问了:我们能否对其他外部设进行读写操作呢?例如:屏幕、键盘、鼠标、U盘、光盘、网络…… ,答案当然是肯定的。
但值得注意
的是,每一种外部设备的读写方式是有所差异的,就比如:写硬盘和写屏幕,读键盘和读网络。那大家想一下,如果一个程序员写代码的时候,必须要把每种外部设备的读和写的方式都理解透彻,是不是太麻烦了!
所以,为了能够让程序员更加方便的对外部设备进行读写操作,我们会在外部设备前抽象出来一层东西,称为:“流”的概念。这样程序员在写文件的时候就不需要关注外部设备了,只需要将数据写到“流”里面去,然后由C语言底层的封装来进行相应的操作,把“流”里面的数据分发到不同的外部设备当中去。反之亦是如此。 如下图所示。抽象的来说“流”就相当于一个中转站,能够将数据更具不同的外部设备读写的方式来进行相应的操作。 如此这些外部设备的细节就不需要用户来关注,用户只需要关注“流”就可以了(这里的“流”指的是向哪个外部设备进行的操作)。至于“流”是如何做到向不同外部设备读写的,这是在C语言底层就已经实现好的,不需要我们关心。
所以,为了能够让程序员更加方便的对外部设备进行读写操作,我们会在外部设备前抽象出来一层东西,称为:“流”的概念。这样程序员在写文件的时候就不需要关注外部设备了,只需要将数据写到“流”里面去,然后由C语言底层的封装来进行相应的操作,把“流”里面的数据分发到不同的外部设备当中去。反之亦是如此。 如下图所示。抽象的来说“流”就相当于一个中转站,能够将数据更具不同的外部设备读写的方式来进行相应的操作。 如此这些外部设备的细节就不需要用户来关注,用户只需要关注“流”就可以了(这里的“流”指的是向哪个外部设备进行的操作)。至于“流”是如何做到向不同外部设备读写的,这是在C语言底层就已经实现好的,不需要我们关心。
“流”是一个比较抽象的概念,数据就像水管里的水流,可以从内存中流向外部设备,也可以从外部设备流向内存,但只能单方向的流。由此可见“流”是有明确的方向性的,所以可以将“流”分为两种:以内存为第一人称,数据从内存向外流的称为输出流,数据由外向内存流的称为输入流。
还值得补充的一点是,不知道大家有没有发现,我们在对一个文件操作前必须先打开它,获得与之关联的文件指针,这个指针就可以称为“文件流”,因为这个指针指向了数据的目的地 / 源头。但我们在对屏幕写出数据时或从键盘上读入数据时,并没有对这些外部设备进行打开操作获得所对应的“流”啊,而且在scanf和printf操作的时候也没有要求你给出数据的流向,最后却还能实现,这是为什么呢?
因为任意一个C程序只要运行起来,就会默认打开3个“流”:
stdin —— 标准输入流(键盘)
stdout —— 标准输出流(屏幕)
stderr —— 标准错误流(屏幕)
所以printf()会默认将数据发送到stdout这个“流”上,scanf()会默从stdin这个“流”上读取数据,不需要我们手动打开和关闭“流”。但对于文件来说,我们就必须先打开这个文件从而获得这个“流”,然后才能从这个“流”里面读取数据或向这个“流”里面写数据,最后还得关闭“流”。
那有同学就要问了:能不能用格式化输出函数fprintf()来向屏幕上输出一段内容?答案当然是可以的.