当前位置: 首页 > news >正文

Linux操作系统--基础I/O(上)

目录

1.回顾C文件接口

stdin、stdout、stderr

2.系统文件I/O

3.接口介绍

4.open函数返回值

5.文件描述符fd

5.1 0&1&2


1.回顾C文件接口

hello.c写文件

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

hello.c读文件

#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 friend!\n";while(1){//size_t s = fread(buf,strlen(msg),1,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;
}

stdin、stdout、stderr

stdin(0):键盘文件 

stdout(1):显示器文件

stderr(2):显示器文件。(错误信息输出)
进程会默认打开键盘、显示器

三个流的类型都是FILE* ,fopen返回值类型,文件指针

2.系统文件I/O

操作文件,除了上述C接口,我们还可以采用系统接口来进行文件访问。(文件其实是在磁盘上的,磁盘是外部设备,访问磁盘文件其实是访问硬件。几乎所有的库只要是访问硬件设备,必定要封装系统调用,因为之前讲到过,操作系统并不相信用户,不会与用户直接接触,所以提供了接口给用户)

先来直接以代码的形式,实现上面一模一样的代码:

hello.c写文件

#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>int main()
{umask(0);//修改默认权限掩码int fd = open("myfile",O_WRONLY|O_CREAT,0644);if(fd<0){perror("open");return 1;}int count = 5;const char *msg = "hello friend\n";int len = strlen(msg);while(count--){write(fd,msg,len);//fd:后面讲, msg:缓冲区首地址, len:本次读取,期望写入多少个字节的数据, //返回值:实际写了多少字节数据}close(fd);return 0;
}

hello.c读文件

#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>int main()
{int fd = open("myfile",O_RDONLY);if(fd<0){perror("open");return 1;}const char *msg = "hello friend\n";char buf[1024];while(1){size_t s = read(fd,buf,strlen(msg));if(s>0){printf("%s",buf);}else{break;}}close(fd);return 0;
}

3.接口介绍

open

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.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

4.open函数返回值

在认识返回值之前,下来认识两个概念:

  1. 系统调用:系统调用是操作系统提供给用户程序的一种接口,用于让用户程序请求操作系统内核提供的服务。当用户程序需要执行一些特权操作(如文件操作、进程管理等),无法直接访问硬件资源,需要通过系统调用向操作系统内核发出请求。系统调用是通过中断或异常机制实现的,可以看作是用户程序与操作系统内核之间的桥梁。

  2. 库函数:库函数是一组提供特定功能的函数,被封装在软件库中以供程序开发者使用。库函数通常是由编程语言或第三方开发者编写的,用于简化开发过程、提高代码的可重用性和可维护性。库函数可以包含在标准库或第三方库中,程序可以通过链接库函数的方式来调用其中的功能
  • 上面的fopen fclose fread fwrite都是C标准库当中的函数,我们称之为库函数(libc)。
  • 而,open close read write lseek都属于系统提供的接口,称之为系统调用接口

系统调用接口和库函数的关系一目了然

所以,可以认为,f#系列的函数,都是对系统调用的封装,方便二次开发

5.文件描述符fd

文件描述符就是一个整数

5.1 0&1&2

  • Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0,标准输出1,标准错误2.
  • 0,1,2对应的物理设备一般是:键盘,显示器,显示器                        

所以输入输出还可以采用如下方式:

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>int main()
{char buf[1024];ssize_t s = read(0,buf,sizeof(buf));if(s>0){buf[s]=0;write(1,buf,strlen(buf));write(2,buf,strlen(buf));}return 0;
}

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

相关文章:

  • 如何获取静态IP地址?完整教程
  • 第15章:MCP服务端项目开发实战:性能优化
  • 蓝桥杯 1. 四平方和
  • 深入详解人工智能数学基础——概率论中的贝叶斯深度学习
  • 今日行情明日机会——20250424
  • Python基础语法:字面量,注释,关键字,标识符,变量和引用,程序执行的3大流程
  • 指纹浏览器电商防关联功能深度解析:技术原理与实战应用
  • Docker 磁盘占用盘查和清理
  • 深入解析 Android Native Hook
  • 【硬核干货】JetBrains AI Assistant 干货笔记
  • react nativeWebView跨页面通信
  • PostgreSQL 中的权限视图
  • JavaScript 异步编程与请求取消全指南
  • 11.原型模式:思考与解读
  • DMG 文件隐写
  • React Native 安卓端 android Image 播放gif webp 动态图
  • 学习MySQL的第十一天
  • 把dll模块注入到游戏进程的方法_挂起进程注入
  • c加加学习之day06->STL标准库->day01
  • 从零开始在Win上添加一块QEMU开发板(四)实现简单USART
  • 五一假期上海路网哪里易拥堵?怎么错峰更靠谱?研判报告来了
  • 中国与肯尼亚签署共同发展经济伙伴关系框架协定
  • 国家市场监管总局:组织销毁侵权假冒服装、食药等3300吨
  • 深圳大学传播学院院长巢乃鹏已任深圳大学副校长
  • 无视规范开“远端”、企业云端被窃密,国安部:莫让运维成运“危”
  • 中国气象局:针对山西、广西、陕西启动抗旱四级应急响应