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

Liunx文件系统和基础IO

文件系统和基础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 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模拟用户在浏览器中的操作&#xff0c;比如点击按钮。在某些场景下&#xff0c;我们需要模拟鼠标悬停的操作&#xff0c;来触发一些隐藏的元素。本文将介绍Python Selenium实现鼠标悬停操作。 鼠标悬停&#xff0c;即当光标与其名称表示的元素重叠时触发的事件&…...

简介:基于 OpenTiny 组件库的 rendereless 无渲染组件架构

在 HAE 自研阶段&#xff0c;我们实现的数据双向绑定、面向对象的 JS 库、配置式开发的注册表等特性&#xff0c;随着前端技术的高速发展现在已经失去存在的意义&#xff0c;但是在 AUI 阶段探索的新思路新架构&#xff0c;经过大量的业务落地验证&#xff0c;再次推动前端领域…...

tcp 连接数上限突破

连接数上限条件 文件句柄的限制 一个tcp连接就需要占用一个文件描述符&#xff0c;一旦文件描述符用完&#xff0c;新的连接就会返回给我们错误是&#xff1a;Can’topen so many files。linux系统出于安全角度的考虑&#xff0c;在多个维度对于可打开的文件描述符进行了限制…...

解决 mmseg/models/decode_heads/mask2former_head.py 中__init__()关键字参数错误

目录 【1 - 问题描述】 【2 - 报错位置检查】 【3 - 问题解决】 【4 - 解决的过程】 【1 - 问题描述】 在mmsegmentation中运行mask2former模型的分割任务遇到报错缺少关键字的错误&#xff1a; TypeError: class Mask2FormerHead in mmseg/models/decode_heads/mask2form…...

​如何使用 ArcGIS Pro 分析爆炸波及建筑

假设在某栋建筑内发生了爆炸&#xff0c;需要根据爆炸的范围分析出来波及的建筑&#xff0c;对于这一需求&#xff0c;我们可以通过ArcGIS Pro来实现&#xff0c;这里为大家介绍一下分析的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载…...

LoadBalancer (本地负载均衡)

1.loadbalancer本地负载均衡客户端 VS Nginx服务端负载均衡区别 Nginx是服务器负载均衡&#xff0c;客户端所有请求都会交给nginx&#xff0c;然后由nginx实现转发请求&#xff0c;即负载均衡是由服务端实现的。 loadbalancer本地负载均衡&#xff0c;在调用微服务接口时候&a…...

每日一题 第一期 洛谷 铺地毯

[NOIP2011 提高组] 铺地毯 https://www.luogu.com.cn/problem/P1003 题目描述 为了准备一个独特的颁奖典礼&#xff0c;组织者在会场的一片矩形区域&#xff08;可看做是平面直角坐标系的第一象限&#xff09;铺上一些矩形地毯。一共有 n n n 张地毯&#xff0c;编号从 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 信号量/灯 网络编程系列文章&#xff1a; 第1章 Linux系统编程入门&#xff08;上&#xff09; 第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 总结尾序 一、基本概念 常见的应用层协议&#xff1a; HTTPS (HyperText Transfer Protocol Sec…...

股市新手福音:河北源达“财源滚滚”让投资变得更简单

在浩渺的股市海洋中&#xff0c;每一位投资者都渴望找到一把能够指引航向的罗盘。尤其是对于股市新手来说&#xff0c;面对复杂的市场环境、纷繁的个股信息以及不断变化的投资策略&#xff0c;如何快速入门、精准选股&#xff0c;无疑是一大挑战。而河北源达信息技术股份有限公…...

2024.02.14 校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、校招&社招 | 中国电子信息产业集团有限公司校园招聘 校招&社招 | 中国电子信息产业集团有限公司校园招聘 2、校招&社招 | 中核光电2024年春季校园招聘开启&#xff01; 校…...

5.Java并发编程—JUC线程池架构

JUC线程池架构 在Java开发中&#xff0c;线程的创建和销毁对系统性能有一定的开销&#xff0c;需要JVM和操作系统的配合完成大量的工作。 JVM对线程的创建和销毁&#xff1a; 线程的创建需要JVM分配内存、初始化线程栈和线程上下文等资源&#xff0c;这些操作会带来一定的时间和…...

llama2c(4)之forward、sample、decode

1、forward float* logits forward(transformer, token, pos); 输入transformer的参数&#xff0c;当前token&#xff0c;pos位置&#xff0c;预测出下一个token的预测值&#xff08;用矩阵乘&#xff0c;加减乘除等运算构成Transformer&#xff09; 其中&#xff0c;logits如…...

20240312-2-贪心算法

贪心算法 是每次只考虑当前最优&#xff0c;目标证明每次是考虑当前最优能够达到局部最优&#xff0c;这就是贪心的思想&#xff0c;一般情况下贪心和排序一起出现&#xff0c;都是先根据条件进行排序&#xff0c;之后基于贪心策略得到最优结果。 面试的时候面试官一般不会出贪…...

前端 --- 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库&#xff0c;为防止冲突&#xff0c;删去编译好的curl库。 对以json数据的解析使…...

12、设计模式之代理模式(Proxy)

一、什么是代理模式 代理模式属于结构型设计模式。为其他对象提供一种代理以控制对这个对象的访问。 在某些情况下&#xff0c;一个对象不适合或者不能直接引用另一个对象&#xff0c;而代理对象可以在客户端和目标对象之间起到中介的作用。 二、分类 代理模式分为三类&#…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...