Linux——基础IO

1、文件基础知识

2、文件接口

3、文件描述符

4、重定向原理

5、如何理解一切皆文件


1、文件基础知识

1、文件=文件内容 + 属性(也是数据)。

2、文件的所有操作,无外乎:对内容、对属性。

3、是进程在访问文件,文件在磁盘(硬件)放着,是操作系统提供的文件类调用接口能让用户写入,且操作系统层面的接口只有一套。

4、在linux中,一切皆文件,包括键盘、显示器等。


2、文件接口

C文件接口

写文件

#include <stdio.h>
#include <string.h>
int main()
{
 FILE *fp = fopen("myfile", "w");
 if(!fp){
 printf("fopen error!\n");
 }
 const char *msg = "hello log.txt!\n";
 int count = 5;
 while(count--){
 fwrite(msg, strlen(msg), 1, fp);
 }
 fclose(fp);
 return 0;
}

读文件

#include <stdio.h>
#include <string.h>
int main()
{
 FILE *fp = fopen("myfile", "r");
 if(!fp){
 printf("fopen error!\n");
 }
 char buf[1024];
 const char *msg = "hello log.txt!\n";
 while(1){
 //注意返回值和参数,此处有坑,仔细查看man手册关于该函数的说明
 ssize_t s = fread(buf, 1, strlen(msg), fp);
 if(s > 0){
 buf[s] = 0;
 printf("%s", buf);
 }
 if(feof(fp)){
 break;
 }
 }
 fclose(fp);
 return 0;
}

 输出信息到显示器的方法:

#include <stdio.h>
#include <string.h>
int main()
{
const char *msg = "hello fwrite\n";
fwrite(msg, strlen(msg), 1, stdout);
printf("hello printf\n");
fprintf(stdout, "hello fprintf\n");
return 0;
}

 C语言会默认打开三个输入输出流,分别是stdin,stdout,stderr。

系统文件I/O

用系统接口来进行文件访问,实现和上面一模一样的代码:

写文件:

 读文件:

 

接口介绍:open

#include <sys/types.h>

#include <sys/stat.h>

#include <fctnl.h>

int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);      

pathname:要求打开或创建的目标文件

flags:打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags。

参数:

        O_RDONLY :只读打开

        O_WRONLY:只写打开

        O_RDWR    :读、写打开

这三个常量,必须指定一个且只能指定一个

        O_CREAT   :若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限

        O_APPEND:追加写

返回值:

        成功:新打开的文件描述符

        失败:-1


3、文件描述符

文件描述符就是一个小整数,Linux进程默认情况下会有三个缺省打开的文件描述符,分别是标准输入0,标准输出1,标准错误2。

0,1,2对应的物理设备一般是:键盘,显示器,显示器。

打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了file结构体,表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*files,指向一张表files_struct,该表最重要的部分就是包含一个指针数组,每个元素都是一个指向打开文件的指针。所以,本质上,文件描述符就是该数组的下标。所以,只要有文件描述符,就可以找到对应的文件。

文件描述符的分配规则

如果关闭0或者2

 

 fd便变成了0或2

fd分配规则:在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。


4、重定向原理

上面的例子没有举close(1)的例子,因为会发生输出重定向,先看现象:

运行程序后发现没有东西被输出到显示器上,因为内容被输出到了文件中 

close(1)便实现了输出从显示器到文件的重定向

输出重定向原理:

当close(1)后,凡是往1号文件描述写的内容,都写到了log.txt中,而不是标准输出即显示屏中,但是在操作系统层面上,stdout对应的是1号文件,所以当调用如printf,fprint等输出函数时,它们的内容也会输出到1号文件所指向的log.txt中,这就是输出重定向的原理。

使用dup2系统调用实现重定向

 

 

 int dup2 (int oldfd, int newfd);

这个函数的逻辑是将oldfd指向的地址拷贝给newfd,就比如上面的代码将原本3号文件指向的log.txt的地址拷贝给了1号文件,从而断开了1号文件与标准输出的连接来实现了输出重定向。


5、如何理解一切皆文件

linux是用C语言编写的,那么如何用C语言实现面向对象呢?

在C++中,类是实现面向对象的方法,所以用C语言去模拟类便可以解决面向对象,类中包含1、成员属性,2、成员方法。C语言中结构体中的数据可以看作是成员属性,那么成员方法该如何实现,那就是函数指针。

对于一台电脑,它有磁盘、显示器、键盘、网卡、显卡等硬件,它们对应的底层不同,那么对应的操作方法也就不同,但它们都是外设,所以每一个设备的核心访问函数都可以是read,write(I/O)。

所有的设备,都可以有自己的read和write,但是它们代码的实现一定是不一样的,所以linux就给它们各自都提供一个struct file。

 

 那么在这所有struct file的上层,就没有任何硬件区别了,这就是linux下一切皆文件的理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

双葉Souyou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值