Liunx文件系统和基础IO

news2024/12/22 17:11:44

文件系统和基础IO

  • 基础IO
    • c语言基础IO函数
    • 当前路径和标准流
    • 系统IO
    • 系统调用函数
    • 重定向
    • FILE文件结构体
  • 在谈缓存区问题
  • 理解文件系统
    • 初识inode

基础IO

c语言基础IO函数

  1. 打开与关闭
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);
}

系统调用函数

  1. 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 0
	int _blksize;
#else
	int _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拿出来做修改再放回去,这就是所谓的基本单位。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1512928.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java异常分类(二)

RuntimeException 运行时异常&#xff1a; 派生于 RuntimeException 的异常&#xff0c;如被 0 除、数组下标越界、空指针等&#xff0c;其产生比较频繁&#xff0c;处理麻烦&#xff0c;如果显式的声明或捕获将会对程序可读性和运行效率影响很大。因此由系统自动检测并将它们交…

Vcenter 定制创建 Rocky Linux 虚拟机

文章目录 1. 图形化安装2. 初始化配置 1. 图形化安装 2. 初始化配置 Centos 8.2 指南

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的商品识别系统(深度学习+UI界面+训练数据集+Python代码)

摘要&#xff1a;在零售行业的技术进步中&#xff0c;开发商品识别系统扮演着关键角色。本博文详细阐述了如何利用深度学习技术搭建一个高效的商品识别系统&#xff0c;并分享了一套完整的代码实现。系统采用了性能强劲的YOLOv8算法&#xff0c;同时对YOLOv7、YOLOv6、YOLOv5等…

RabbitMQ 面试题及答案整理,最新面试题

RabbitMQ的核心组件有哪些&#xff1f; RabbitMQ的核心组件包括&#xff1a; 1、生产者&#xff08;Producer&#xff09;&#xff1a; 生产者是发送消息到RabbitMQ的应用程序。 2、消费者&#xff08;Consumer&#xff09;&#xff1a; 消费者是接收RabbitMQ消息的应用程序…

L2-035 完全二叉树的层序遍历(Python)

L2-035 完全二叉树的层序遍历 分数 25 全屏浏览 切换布局 作者 陈越 单位 浙江大学 一个二叉树&#xff0c;如果每一个层的结点数都达到最大值&#xff0c;则这个二叉树就是完美二叉树。对于深度为 D 的&#xff0c;有 N 个结点的二叉树&#xff0c;若其结点对应于相同深度…

吴恩达 x Open AI ChatGPT ——如何写出好的提示词视频核心笔记

核心知识点脑图如下&#xff1a; 1、第一讲&#xff1a;课程介绍 要点1&#xff1a; 上图展示了两种大型语言模型&#xff08;LLMs&#xff09;的对比&#xff1a;基础语言模型&#xff08;Base LLM&#xff09;和指令调整语言模型&#xff08;Instruction Tuned LLM&#xff0…

[LeetCode][110]平衡二叉树

题目 110.平衡二叉树 给定一个二叉树&#xff0c;判断它是否是平衡二叉树。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,3,3,null,null,4,4] 输出&#xff1a;false 示例 3&…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的农作物害虫检测系统(深度学习模型+UI界面+训练数据集)

摘要&#xff1a;开发农作物害虫检测系统对于提高农业生产效率和作物产量具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个农作物害虫检测系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5&#xff0…

惬意上手Redis

Redis介绍 Redis&#xff08;全称为REmote Dictionary Server&#xff09;是一个开源的、内存中的数据存储结构&#xff0c;主要用作应用程序缓存或快速相应数据库。 REmote Dictionary Server: 有道翻译Redis是“远程字典服务”&#xff0c;远程不过是远程访问&#xff0c;而…

大模型学习笔记六:Semantic Kernel

文章目录 一、Semantic Kernel介绍和发展1&#xff09;SK 的语言开发进展2&#xff09;SK的生态位3&#xff09;SK基础架构 二、环境搭建1&#xff09;初始化2&#xff09;Semantic Functions&#xff08;不用编写代码&#xff0c;用配置实现回调函数&#xff09;3&#xff09;…

vb oe20.03 ssh nat

环境 virtual boxopeneuler 20.03 LTS网络设置 nat 主机端口可以自行设置&#xff0c;其余三项固定不变。然后即可通过ssh进行连接。

Dynamic Wallpaper v17.4 mac版 动态视频壁纸 兼容 M1/M2

Dynamic Wallpaper Engine 是一款适用于 Mac 电脑的视频动态壁纸&#xff0c; 告别单调的静态壁纸&#xff0c;拥抱活泼的动态壁纸。内置在线视频素材库&#xff0c;一键下载应用&#xff0c;也可导入本地视频&#xff0c;同时可以将视频设置为您的电脑屏保。 应用介绍 Dynam…

pycharm @NotNull parameter ‘module‘ of ...

下载了最新pycharm &#xff0c;无法启动运行 pycharm或者idea中Run/Debug Python项目报错 Argument for NotNull parameter ‘module‘ of … 解决方案 删除项目根目录的 idea 文件夹 随后重启&#xff0c;重新配置即可

探索Linux世界:基本指令(文件查看、时间相关、grep、打包压缩及相关知识)

今天继续介绍一些指令 文章目录 1.cat - 查看文件1.1输出重定向和追加重定向1.2指令echo 2.more 指令3.less - 逐页查看文本文件内容4.head- 显示文件开头部分内容5.tail - 显示文件末尾部分内容5.1输入重定向&#xff08;<&#xff09;5.2管道&#xff08;|&#xff09; 6.…

第2篇【Docker项目实战】使用Docker部署Raneto知识库平台(转载)

【Docker项目实战】使用Docker部署Raneto知识库平台 一、Raneto介绍 1.1 Raneto简介 Raneto是一个免费、开放、简单的 Markdown 支持的 Node.js 知识库。 1.2 知识库介绍 知识库 知识库是指存储和组织知识的系统或库&#xff0c;它包括了各种类型的信息和知识&#xff0c;如…

Nodejs 第五十一章(限流阀)

限流功能 目前我们学习了redis,lua,nodejs&#xff0c;于是可以结合起来做一个限流功能&#xff0c;好比一个抽奖功能&#xff0c;你点击次数过多&#xff0c;就会提示请稍后重试&#xff0c;进行限制&#xff0c;我们来实现一下该功能。 安装依赖 npm i ioredis express代码…

git提交代码描述时如何换行(更新时间24/3/12)

问题复现&#xff08;信心满满使用转义字符换行&#xff09; 解决方法&#xff1a; 写多个-m字符串的结构可以实现自动换行 注意空格 git commit -m"第一行描述" -m"第二行描述" 效果演示&#xff1a;&#xff08;强迫症福利&#xff09;

【20240309】WORD宏设置批量修改全部表格格式

WORD宏设置批量修改全部表格格式 引言1. 设置表格文字样式2. 设置表格边框样式3. 设置所有表格边框样式为075pt4. 删除行参考 引言 这两周已经彻底变为office工程师了&#xff0c;更准确一点应该是Word工程师&#xff0c;一篇文档动不动就成百上千页&#xff0c;表格图片也是上…

导入空管基础数据

1、首先将data.tar.gz解压到自定义目录中 注意&#xff1a;由于数据文件的压缩包比较大&#xff0c;解压过程可能会持续3~5分钟&#xff0c;请耐心等待。 [rootnode3 ~]# cd /opt/software/ [rootnode3 software]# tar -xzf data.tar.gz -C /opt/ 2、利用SQLyog或者其他数据库…

鸿蒙不再适合JS语言开发

ArkTS是鸿蒙生态的应用开发语言。它在保持TypeScript&#xff08;简称TS&#xff09;基本语法风格的基础上&#xff0c;对TS的动态类型特性施加更严格的约束&#xff0c;引入静态类型。同时&#xff0c;提供了声明式UI、状态管理等相应的能力&#xff0c;让开发者可以以更简洁、…