Linux一学就会——系统文件I/O
Linux一学就会——系统文件I/O
有几种输出信息到显示器的方式
#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;
}
这三种都可以输出到屏幕上

是不是有很多疑问fwrite中的“1”和“stdout”到底是什么意思呢?
别急且听我慢慢讲来~
操作系统如何写、读文件
我再写一个程序,先利用系统接口open打开或者创建一个只写的文件“myfile”,然后我们在利用系统接口write把我想输出的信息(一个字符串指针msg)输入到fd所指的文件( myfile )中,之后打开myfile就可以看到我们输入的信息了。
int main()
{umask(0);//掩码清楚,不然你没法给下面open的文件设置权限,不用清除,因为只在本进程有效。int fd=open("myfile",O_WRONLY|O_CREAT,0666);if(fd<0){perror("open");exit(1);//return 1;}int count=5;const char *msg="hello,tom!~\n";while(count--){write(fd,msg,strlen(msg));//msg:缓冲区首地址,这里不能用sizeof(msg),因为msg是指针,他的长度(32位)是4个字节,所以要用strlen。//sleep(1);//<unistd.h>}close(fd);return 0;
}
cat这个文件myfile,输出字符串。

当我把fd给成1的时候,再运行程序,直接打印到了屏幕上。


发现没有?1其实就是stdout
再来做一个实验
int main()
{int fd = open("myfile", O_RDONLY);if (fd < 0){perror("open");return 1;}const char *msg = "hello tom!\n";char buf[1024];while (1){ssize_t s = read(fd, buf, strlen(msg)); // 类比write,就是把fd的内容读到buf中if (s > 0){printf("%s", buf);}else{break;}}close(fd);return 0;
}
我再把fd给成0试一下。
int main()
{int fd = open("myfile", O_RDONLY);if (fd < 0){perror("open");return 1;}const char *msg = "hello tom!\n";char buf[1024];while (1){ssize_t s = read(0, buf, sizeof(buf)); // 类比write,就是把fd的内容(myfile的内容)读到buf所指的文件中if (s > 0){printf("%s", buf);}else{break;}}close(fd);return 0;
}
得到一下的结果,输入什么,按下回车就会立马输出到屏幕上。

stdin & stdout & stderr
C默认会打开三个输入输出流,分别是stdin, stdout, stderr
仔细观察发现,这三个流的类型都是FILE*, fopen返回值类型,文件指针
其实经过刚刚的读写实验可以得出他们的fd: stdin=0,stdout=1,那么stderr=2就可以退出来了。
接口介绍
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
mode_t理解:直接man 手册,比什么都清楚。
open 函数具体使用哪个,和具体应用场景相关,如目标文件不存在,需要open创建,则第三个参数表示创建文件
的默认权限,否则,使用两个参数的open。
举个例子:

这个hello的mode=0x755
write read close lseek ,类比C文件相关接口。
系统调用:open close read write lseek 都属于系统提供的接口,称之为系统调用接口。
库函数:fopen fclose fread fwrite 都是C标准库当中的函数,我们称之为库函数(libc)。

这张图就可以很清晰地描述系统接口和库函数。
其实就是我们所用的这些库函数就是对系统调用的二次封装(不光是c/c++,全部的语言都是这样子对系统调用进行封装)
文件描述符fd
通过上述,可以知道fd就是一个整数,但是什么数据结构可以让我们和整数联结在一起呢?
没错就是数组

我们在自定义一个文件,这个文件的fd就会使3了。依次增加,也会慢慢增加。
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;
}
就可以打印出你输入的内容到屏幕上(两行),一个是out的,一个是err的。

而现在知道,文件描述符就是从0开始的小整数。当我们打开文件时,操作系统在内存中要创建相应的数据结构来
描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进
程和文件关联起来。每个进程都有一个指针*files, 指向一张表files_struct,该表最重要的部分就是包涵一个指针数
组,每个元素都是一个指向打开文件的指针!所以,本质上,文件描述符就是该数组的下标。所以,只要拿着文件
描述符,就可以找到对应的文件
但是有一个规则:发现是结果是: fd=0 或者fd=2 关闭一个,文件描述符的分配规则:在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。关闭的原功能就会消失。
相关文章:
Linux一学就会——系统文件I/O
Linux一学就会——系统文件I/O 有几种输出信息到显示器的方式 #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, &q…...
OpenCV-Python图像阈值
目录 简单阈值 自适应阈值 Otsu的二值化 所谓的图像阈值,就是图像二值化,什么是二值化,就是只有0和1,没有其他的。在OpenCV的图像里面,二值化表示图像的像素为0和255,并没有其他的值,它跟灰度…...
LangChain-Agents 入门指南
LangChain-Agents 入门指南 LangChain-Agents 入门指南注册 Serpapi运行高级 Agents API 测试运行 Google Search其它 Here’s the table of contents: LangChain-Agents 入门指南 LangChain是一个使用LLMs构建应用程序的工具箱,包含Models、Prompts、Indexes、Mem…...
深度学习-tensorflow 使用keras进行深度神经网络训练
概要 深度学习网络的训练可能会很慢、也可能无法收敛,本文介绍使用keras进行深度神经网络训练的加速技巧,包括解决梯度消失和爆炸问题的策略(参数初始化策略、激活函数策略、批量归一化、梯度裁剪)、重用预训练层方法、更快的优化…...
【NLP开发】Python实现聊天机器人(ChatterBot,集成前端页面)
🍺NLP开发系列相关文章编写如下🍺: 🎈【NLP开发】Python实现词云图🎈🎈【NLP开发】Python实现图片文字识别🎈🎈【NLP开发】Python实现中文、英文分词🎈🎈【N…...
Python 操作 Excel,如何又快又好?
➤数据处理是 Python 的一大应用场景,而 Excel 则是最流行的数据处理软件。因此用 Python 进行数据相关的工作时,难免要和 Excel 打交道。Python处理Excel 常用的系列库有:xlrd、xlwt、xlutils、openpyxl ◈xlrd - 用于读取 Exce…...
Spring Redis 启用TLS配置支持(踩坑解决)
由于线上Redis要启用TLS,搜遍了google百度也没一个标准的解决方案,要不这个方法没有,要不那个类找不到...要不就是配置了还是一直连不上redis.... 本文基于 spring-data-redis-2.1.9.RELEASE 版本来提供一个解决方案: 1.运维那边提供过来三个文件,分别是redis.crt redis.key …...
centOS7忘记登录密码该如何重新修改登录密码
文章目录 前言一、重新修改登录密码1.1、第一步1.2、第二步1.3、第三步1.4、第四步1.5、第五步1.6、第六步1.7、第七步1.8、第八步 前言 忘记密码并不可怕,只要学会方法,密码随时都可以找回。 一、重新修改登录密码 1.1、第一步 当打开centOS7之后忘记…...
揭开基于 AI 的推荐系统的神秘面纱:深入分析
人工智能 (AI) 以多种方式渗透到我们的生活中,使日常任务更轻松、更高效、更个性化。人工智能最重要的应用之一是推荐系统,它已成为我们数字体验不可或缺的一部分。从在流媒体平台上推荐电影到在电子商务网站上推荐产品࿰…...
MySQL的事务特性、事务特性保证和事务隔离级别
事务是指要么所有的操作都成功执行,要么所有的操作都不执行的一组数据库操作。 一、MySQL提供了四个事务特性,即ACID: 1. 原子性(Atomicity):一个事务中的所有操作要么全部提交成功,要么全部回…...
shell脚本----函数
文章目录 一、函数的定义1.1 shell函数:1.2函数如何定义 二、函数的返回值三、函数的传参四、函数变量的作用范围五、函数的递归六、函数库 一、函数的定义 1.1 shell函数: 使用函数可以避免代码重复使用函数可以将大的工程分割为若干小的功能模块,代码的可读性更…...
( 位运算 ) 693. 交替位二进制数 ——【Leetcode每日一题】
❓693. 交替位二进制数 难度:简单 给定一个正整数,检查它的二进制表示是否总是 0、1 交替出现:换句话说,就是二进制表示中相邻两位的数字永不相同。 示例 1: 输入:n 5 输出:true 解释&#…...
http简述
HTTP(Hypertext Transfer Protocol)是一种用于在Web上传输数据的协议。它是Web的基础,使得我们能够在互联网上访问和共享信息。本文将介绍HTTP的基本概念、工作原理、请求和响应、状态码、安全性和未来发展等方面。 一、HTTP的基本概念 HTT…...
一顿饭的事儿,搞懂了Linux5种IO模型
大家好,我是老三,人生有三大难题,事业、爱情,和 ——这顿吃什么! 人在家中躺,肚子饿得响,又到了不得不吃的时候,这顿饭该怎么吃?吃什么呢? Linux里有五种I…...
C#面向对象的概念
C#面向对象的概念 C#是一种面向对象的编程语言,面向对象编程的核心是将程序中的数据和操作封装在一个对象中。下面是一些面向对象的概念: 类(Class):类是用来描述一类对象的属性和方法的模板或蓝图,它定义…...
探索学习和入门使用GitHub Copilot:提升代码开发的新利器
目录 引言1. 什么是GitHub Copilot?2. 入门使用GitHub Copilot3. GitHub Copilot的基础知识4. GitHub Copilot的应用场景结论 在最近的开发工作中,发现了一个比较实用的工具,github copilot,这是一款基于人工智能的代码助手工具&a…...
在字节跳动做了6年软件测试,4月无情被辞,想给划水的兄弟提个醒
先简单交代一下背景吧,某不知名 985 的本硕,17 年毕业加入字节,以“人员优化”的名义无情被裁员,之后跳槽到了有赞,一直从事软件测试的工作。之前没有实习经历,算是6年的工作经验吧。 这6年之间完成了一次…...
常见信号质量问题、危害及其解决方法-信号完整性-过冲、噪声、回勾、边沿缓慢
概述 在电路设计中,“信号”始终是工程师无法绕开的一个知识点。不管是在设计之初,还是在测试环节中,信号质量问题都值得关注。在本文中,主要介绍信号相关的四类问题:信号过冲、毛刺(噪声)、回…...
Java 自定义注解及使用
目录 一、自定义注解1.使用 interface 来定义你的注解2.使用 Retention 注解来声明自定义注解的生命周期3.使用 Target 注解来声明注解的使用范围4.添加注解的属性 二、使用自定义的注解1.将注解注在其允许的使用范围2.使用反射获取类成员变量上的所有注解3.反射获取成员变量上…...
ChatGPT的强化学习部分介绍——PPO算法实战LunarLander-v2
PPO算法 近线策略优化算法(Proximal Policy Optimization Algorithms) 即属于AC框架下的算法,在采样策略梯度算法训练方法的同时,重复利用历史采样的数据进行网络参数更新,提升了策略梯度方法的学习效率。 PPO重要的突…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
基于stm32F10x 系列微控制器的智能电子琴(附完整项目源码、详细接线及讲解视频)
注:文章末尾网盘链接中自取成品使用演示视频、项目源码、项目文档 所用硬件:STM32F103C8T6、无源蜂鸣器、44矩阵键盘、flash存储模块、OLED显示屏、RGB三色灯、面包板、杜邦线、usb转ttl串口 stm32f103c8t6 面包板 …...
Springboot多数据源配置实践
Springboot多数据源配置实践 基本配置文件数据库配置Mapper包Model包Service包中业务代码Mapper XML文件在某些复杂的业务场景中,我们可能需要使用多个数据库来存储和管理不同类型的数据,而不是仅仅依赖于单一数据库。本技术文档将详细介绍如何在 Spring Boot 项目中进行多数…...
