Liunx文件系统和基础IO
基础IO
c语言基础IO函数
- 打开与关闭
FILE *fopen(char *filename, const char *mode);

选项还可以是 r/w/a+ 意味着为可读可写打开。

2. 写入和读取
(1) 字符的写入和读取
int fputc( int c, FILE *stream );
int fgetc( FILE *stream );


格式化输出和格式化输入

文件是否错误:

当前路径和标准流
所有的文件操作函数生成的文件都在当前路径,这个当前路径其实就是工作目录。工作目录查看方法:
proc文件夹中。
标准流:
extern FILE *stdin;//标准输入流
extern FILE *stdout;//标准输出流
extern FILE *stderr;//标准错误流
当我们运行c语言时,默认打开三个流:其中,标准输入流对应的设备就是键盘,标准输出流和标准错误流对应的设备都是显示器。
stdin、stdout以及stderr是C标准库下的标准输入输出错误流,其他语言如C++也有对应的标准输入输出错误流:cin、cout和cerr。
系统IO

我们在前面学习了 Liunx中,用户不能直接访问操作系统。用户必须通过接口访问。接口既有普通函数接口,也有系统调用接口。c的库函数对不同操作系统的系统调用接口用相同的c语言接口进行封装,让c语言有了跨平台性。
介绍一个小知识点 :位图传参
基本原理:


#define ONE 1
#define TWO (1<<1)
#define THREE (1<<2)
#define FOUR (1<<3)
#define FIVE (1<<4)void Print(int flag)
{if(flag & ONE) printf("1\n");if(flag & TWO) printf("2\n");if(flag & THREE) printf("3\n");if(flag & FOUR) printf("4\n");if(flag & FIVE) printf("5\n");
}int main()
{Print(ONE);printf("----------------------\n");Print(TWO);printf("----------------------\n");Print(ONE|TWO);printf("----------------------\n");Print(THREE|FOUR|FIVE);printf("----------------------\n");Print(ONE|TWO|THREE|FOUR|FIVE);
}
系统调用函数
- open
int open(const char *pathname, int flags, mode_t mode);
open的第一个参数:文件名
-
若pathname以路径的方式给出,则当需要创建该文件时,就在pathname路径下进行创建。
-
若pathname以文件名的方式给出,则当需要创建该文件时,默认在当前路径下进行创建。(注意当前路径的含义)

例如:以只写的方式打开文件,当目标文件不存在时自动创建文件,则参数设置如下:
O_WRONLY | O_CREAT
参数 mode:
open函数的第三个参数是mode,表示创建文件的默认权限。
例如,将mode设置为0666,则文件创建出来的权限如下:
但实际上创建出来文件的权限值还会受到umask(文件默认掩码)的影响,实际创建出来文件的权限为:mode&(~umask)。umask的默认值一般为0002,当我们设置mode值为0666时实际创建出来文件的权限为0664。
文件描述符
open函数的返回值是新打开文件的文件描述符

那么问题来了 0 1 2去哪里了? 是事上0 1 2 正是我们的标准三流
实际上这里所谓的文件描述符本质上是一个指针数组的下标,指针数组当中的每一个指针都指向一个被打开文件的文件信息,通过对应文件的文件描述符就可以找到对应的文件信息。
close
系统接口中使用close函数关闭文件,close函数的函数原型如下:
int close(int fd);
使用close函数时传入需要关闭文件的文件描述符即可,若关闭文件成功则返回0,若关闭文件失败则返回-1。
write
系统接口中使用write函数向文件写入信息,write函数的函数原型如下:
size_t write(int fd, const void *buf, size_t count);
我们可以使用write函数,将buf位置开始向后count字节的数据写入文件描述符为fd的文件当中。
- 如果数据写入成功,实际写入数据的字节个数被返回。
- 如果数据写入失败,-1被返回。
文件描述符fd
我们在前面已经知道了文件描述符是open函数的返回值,就说文件描述符fd和被打开的文件有着千丝万缕的关系。

这个数组管理着所有被打开的文件。

重定向
我们关闭 1 标准输出流 然后重新打开一个。写入到stdout
我们试着写入stdout:结果也是一样。
在打开新接口时,会自动选用最小的接口作为新的函数接口。
dup2的函数调用


dup2通过更换文件描述符fd 达到了重定向的功能。
FILE文件结构体
FILE文件是c语言中掌管文件的一个结构体。接下来,我们看看他封装了什么:
typedef struct _IO_FILE FILE;struct _IO_FILE {int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags//缓冲区相关/* The following pointers correspond to the C++ streambuf protocol. *//* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */char* _IO_read_ptr; /* Current read pointer */char* _IO_read_end; /* End of get area. */char* _IO_read_base; /* Start of putback+get area. */char* _IO_write_base; /* Start of put area. */char* _IO_write_ptr; /* Current put pointer. */char* _IO_write_end; /* End of put area. */char* _IO_buf_base; /* Start of reserve area. */char* _IO_buf_end; /* End of reserve area. *//* The following fields are used to support backing up and undo. */char *_IO_save_base; /* Pointer to start of non-current get area. */char *_IO_backup_base; /* Pointer to first valid character of backup area */char *_IO_save_end; /* Pointer to end of non-current get area. */struct _IO_marker *_markers;struct _IO_FILE *_chain;int _fileno; //封装的文件描述符
#if 0int _blksize;
#elseint _flags2;
#endif_IO_off_t _old_offset; /* This used to be _offset but it's too small. */#define __HAVE_COLUMN /* temporary *//* 1+column number of pbase(); 0 is unknown. */unsigned short _cur_column;signed char _vtable_offset;char _shortbuf[1];/* char* _save_gptr; char* _save_egptr; */_IO_lock_t *_lock;
#ifdef _IO_USE_OLD_IO_FILE
};
我们分别介绍重要部分:

这是c语言自带的文件缓存区。

这就是fd。找到这个之后,我们现在终于明白了,整个结构体就是为了封装fd。open函数在上层为用户申请FILE结构体变量,并返回该结构体的地址(FILE*),在底层通过系统接口open打开对应的文件,得到文件描述符fd,并把fd填充到FILE结构体当中的_fileno变量中,至此便完成了文件的打开操作。
而C语言当中的其他文件操作函数,比如fread、fwrite、fputs、fgets等,都是先根据我们传入的文件指针找到对应的FILE结构体,然后在FILE结构体当中找到文件描述符,最后通过文件描述符对文件进行的一系列操作。
在谈缓存区问题
缓存区在我们刚学之时就是一个很难理解的问题,现在我们写一段代码,再次探索缓存区。

我们把1号从stdout变成了fd,意味着fd会被写入3条指令。
神奇的是

接下来我们就探索这种神奇的现象:
输出的结果就不一样了,C语言函数fprintf和fwrite执行了两次,系统调用write执行了一次,为什么呢?
这就与『 语言层面』上的『 缓冲区』有关了。
首先,缓冲策略有以下几种:
- 无缓冲。
- 行缓冲。(常见的对显示器进行刷新数据)——遇到\n刷新
- 全缓冲。(常见的对磁盘文件写入数据)——写满缓冲区才刷新

c语言自带的缓存区:凡是使用c语言的库函数调用的每个函数都会维护一个缓冲区,执行代码之后,因为文件是全缓冲则成这样:


理解文件系统
现在,我们在冲文件磁盘在看操作系统。
初识inode
- 磁盘文件由两部分构成,分别是文件内容和文件属性。文件内容就是文件当中存储的数据,文件属性就是文件的一些基本信息,例如文件名、文件大小以及文件创建时间等信息都是文件属性,文件属性又被称为元信息。
接下来我们查看文件的详细信息:

磁盘理解:
一个扇区的大小为512字节,但是操作系统认为512字节太小了,访问效率太慢了,所以操作系统将连续的8个扇区作为一个基本数据块,即4KB, 所以这4KB就是IO的基本单位,也就是说只要需要修改数据,哪怕再小,操作系统也要将这4KB拿出来做修改再放回去,这就是所谓的基本单位。
相关文章:
Liunx文件系统和基础IO
文件系统和基础IO 基础IOc语言基础IO函数当前路径和标准流系统IO系统调用函数重定向FILE文件结构体 在谈缓存区问题理解文件系统初识inode 基础IO c语言基础IO函数 打开与关闭 FILE *fopen(char *filename, const char *mode);选项还可以是 r/w/a 意味着为可读可写打开。 2…...
【Python+Selenium学习系列5】Selenium特殊元素定位之-鼠标悬停操作
前言 Selenium模拟用户在浏览器中的操作,比如点击按钮。在某些场景下,我们需要模拟鼠标悬停的操作,来触发一些隐藏的元素。本文将介绍Python Selenium实现鼠标悬停操作。 鼠标悬停,即当光标与其名称表示的元素重叠时触发的事件&…...
简介:基于 OpenTiny 组件库的 rendereless 无渲染组件架构
在 HAE 自研阶段,我们实现的数据双向绑定、面向对象的 JS 库、配置式开发的注册表等特性,随着前端技术的高速发展现在已经失去存在的意义,但是在 AUI 阶段探索的新思路新架构,经过大量的业务落地验证,再次推动前端领域…...
tcp 连接数上限突破
连接数上限条件 文件句柄的限制 一个tcp连接就需要占用一个文件描述符,一旦文件描述符用完,新的连接就会返回给我们错误是:Can’topen so many files。linux系统出于安全角度的考虑,在多个维度对于可打开的文件描述符进行了限制…...
解决 mmseg/models/decode_heads/mask2former_head.py 中__init__()关键字参数错误
目录 【1 - 问题描述】 【2 - 报错位置检查】 【3 - 问题解决】 【4 - 解决的过程】 【1 - 问题描述】 在mmsegmentation中运行mask2former模型的分割任务遇到报错缺少关键字的错误: TypeError: class Mask2FormerHead in mmseg/models/decode_heads/mask2form…...
如何使用 ArcGIS Pro 分析爆炸波及建筑
假设在某栋建筑内发生了爆炸,需要根据爆炸的范围分析出来波及的建筑,对于这一需求,我们可以通过ArcGIS Pro来实现,这里为大家介绍一下分析的方法,希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载…...
LoadBalancer (本地负载均衡)
1.loadbalancer本地负载均衡客户端 VS Nginx服务端负载均衡区别 Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求,即负载均衡是由服务端实现的。 loadbalancer本地负载均衡,在调用微服务接口时候&a…...
每日一题 第一期 洛谷 铺地毯
[NOIP2011 提高组] 铺地毯 https://www.luogu.com.cn/problem/P1003 题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有 n n n 张地毯,编号从 1 …...
Linux 多线程开发
第三章 Linux 多线程开发 3.1 线程3.1.2 线程操作3.1.2 线程属性 3.2 线程同步3.2.1 互斥量/锁3.2.2 死锁3.2.3 读写锁 3.3 生产者消费者模型3.3.1 条件变量3.3.2 信号量/灯 网络编程系列文章: 第1章 Linux系统编程入门(上) 第1章 Linux系统…...
Android 9.0 关于在系统Launcher3中调用截图api总是返回null的解决方案
1.概述 在9.0的系统rom产品定制化开发中,在Launcher3的开发中,在某些时候需要调用截图接口来进行截屏功能实现,而在Launcher3中发现调用系统截屏接口SurfaceControl.screenshot进行截图的时候始终为null, 获取不到系统当前页面的截屏功能,所以需要找到当前截屏失败的原因然…...
openssl3.2 - exp - 用openssl命令行来模拟ECC加解密的全流程
文章目录 openssl3.2 - exp - 用openssl命令行来模拟ECC加解密的全流程概述笔记实验环境实验备注END openssl3.2 - exp - 用openssl命令行来模拟ECC加解密的全流程 概述 工程中要用到ECC加解密, 先去查了资料. 在网上能查到一些大佬们写的ECC加解密实现(基于openssl API), 不…...
【Linux进阶之路】HTTP协议
文章目录 一、基本概念1.HTTP2.域名3.默认端口号4.URL 二、请求与响应1.抓包工具2.基本框架3.简易实现3.1 HttpServer3.2 HttpRequest3.2.1 version13.2.2 version23.2.3 version3 总结尾序 一、基本概念 常见的应用层协议: HTTPS (HyperText Transfer Protocol Sec…...
股市新手福音:河北源达“财源滚滚”让投资变得更简单
在浩渺的股市海洋中,每一位投资者都渴望找到一把能够指引航向的罗盘。尤其是对于股市新手来说,面对复杂的市场环境、纷繁的个股信息以及不断变化的投资策略,如何快速入门、精准选股,无疑是一大挑战。而河北源达信息技术股份有限公…...
2024.02.14 校招 实习 内推 面经
绿*泡*泡VX: neituijunsir 交流*裙 ,内推/实习/校招汇总表格 1、校招&社招 | 中国电子信息产业集团有限公司校园招聘 校招&社招 | 中国电子信息产业集团有限公司校园招聘 2、校招&社招 | 中核光电2024年春季校园招聘开启! 校…...
5.Java并发编程—JUC线程池架构
JUC线程池架构 在Java开发中,线程的创建和销毁对系统性能有一定的开销,需要JVM和操作系统的配合完成大量的工作。 JVM对线程的创建和销毁: 线程的创建需要JVM分配内存、初始化线程栈和线程上下文等资源,这些操作会带来一定的时间和…...
llama2c(4)之forward、sample、decode
1、forward float* logits forward(transformer, token, pos); 输入transformer的参数,当前token,pos位置,预测出下一个token的预测值(用矩阵乘,加减乘除等运算构成Transformer) 其中,logits如…...
20240312-2-贪心算法
贪心算法 是每次只考虑当前最优,目标证明每次是考虑当前最优能够达到局部最优,这就是贪心的思想,一般情况下贪心和排序一起出现,都是先根据条件进行排序,之后基于贪心策略得到最优结果。 面试的时候面试官一般不会出贪…...
前端 --- HTML
1. HTML 结构 1.1 HTML 文件基本结构 <html><head><title>第一个html程序</title></head><body>hello world!</body> </html> html 标签是整个 html 文件的根标签(最顶层标签)head 标签中写页面的属性.body 标签中写的是页…...
curl c++ 实现HTTP GET和POST请求
环境配置 curl //DV2020T环境下此步骤可省略 https://curl.se/download/ 笔者安装为7.85.0版本 ./configure --without-ssl make sudo make install sudo rm /usr/local/lib/curl 系统也有curl库,为防止冲突,删去编译好的curl库。 对以json数据的解析使…...
12、设计模式之代理模式(Proxy)
一、什么是代理模式 代理模式属于结构型设计模式。为其他对象提供一种代理以控制对这个对象的访问。 在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。 二、分类 代理模式分为三类&#…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
