【Linux】文件IO---应用开发角度

news2024/12/23 19:29:39

目录简述

目录

前言:

一、Linux的文件

二、Linux文件系统目录结构

三、文件访问的方式

(1)通用方式:open/read/write/lseek/close

示例:

(2)非通用函数:ioctl/mmap

示例:

(3)函数用法查询

四、系统内核文件:


前言:

初始环节:带着以下的问题,针对性的阅读实践,理解程度更深哈

在 Linux 系统中,一切都是“文件”:普通文件、驱动程序、网络通信等等。所有的操作,都是通过“文件 IO”来操作的。

(1)Linux的文件从哪里来?

(2)Linux文件目录结构是怎么样的?

(3)Linux系统里如何访问文件呢?

(4)Linux系统调用如何进入内核模式?在内核中的文件是如何访问的呢?

接下来的文章内容,将详细的解答上面的问题。如果有一些些帮助,不妨三连关注( ^_^ )。

一、Linux的文件

Linux的文件从哪里来?

Linux的文件既可以是真实保存到存储介质的文件也可以是自身内核提供的虚拟文件,还可以设备节点。如下图所示:

例:可以在Linux系统上查询设备节点,crw(char)对应的字符设备,brw(block)对应块设备,后面主设备号对应哪个驱动,次设备号对应哪个硬件。如下图所示:

二、Linux文件系统目录结构

Linux文件目录结构是怎么样的?

Linux内核源码目录结构:

  • arch/:
    • 包含和硬件体系相关的代码,如:alpha/,arm/,mips/等。
  • block/:
    • 块设备驱动程序调度。
  • crypto/:
    • 常用加密和散列算法,还有一些压缩和CRC校验算法。
  • Documentation/:
    • 内核各部分的通用解释和注释。
  • drivers/:
    • 设备的驱动程序。
  • fs/:
    • 支持的各种的文件系统,如:NTFS,FAT,ETX2/3/4,sysfs,procfs,NFS等。
  • include/:
    • 头文件,与系统相关的头文件放在/include/linux。
  • init/:
    • 内核初始化和启动代码。
  • ipc/:
    • 进程间通信代码:包含进程通信(IPC)机制的实现,如消息队列,信号量和共享内存。
  • kernel/:
    • ​​​​​​​该内核最核心的部分,包括进程进度、定时器等,而和平台相关的一部分放在arch/*/kernel目录下。
  • lib/:
    • ​​​​​​​该目录包含库函数和一些辅助函数,分别是通用内核对象(kobject)处理程序和循环冗余校验(CRC)计算函数等。
  • mm/:
    • ​​​​​​​内存管理相关代码。
  • net/:
    • ​​​​​​​该目录包含网络(无论什么类型的网络)协议相关代码。
  • scripts/:
    • ​​​​​​​该目录包含在内核开发过程中使用的脚本工具,还有其他有用的工具。
  • security/:
    • ​​​​​​​该目录包含安全框架相关代码。
  • sound/:
    • ​​​​​​​该ALSA、OSS音频设备的驱动核心代码和常用设备驱动。
  • usr/:
    • ​​​​​​​实现用于打包和压缩的cpio等。
  • include:
    • ​​​​​​​内核API级别头文件。

三、文件访问的方式

Linux系统里如何访问文件呢?

(1)通用方式:open/read/write/lseek/close

示例:

实现文件的复制

  • 这里打开老文件,没有的话,建立一个新文件(open)。
  • while循环将老文件里的内容写到新文件里(write),循环结束条件---当读不到内容时(read)
  • 最后关闭老文件和新文件(close)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

/*
 * ./copy 1.txt 2.txt
 * argc    = 3
 * argv[0] = "./copy"
 * argv[1] = "1.txt"
 * argv[2] = "2.txt"
 */
int main(int argc, char **argv)
{
	int fd_old, fd_new;
	char buf[1024];
	int len;
	
	/* 1. 判断参数 */
	if (argc != 3) 
	{
		printf("Usage: %s <old-file> <new-file>\n", argv[0]);
		return -1;
	}

	/* 2. 打开老文件 */
	fd_old = open(argv[1], O_RDONLY);
	if (fd_old == -1)
	{
		printf("can not open file %s\n", argv[1]);
		return -1;
	}

	/* 3. 创建新文件 */
	fd_new = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
	if (fd_new == -1)
	{
		printf("can not creat file %s\n", argv[2]);
		return -1;
	}

	/* 4. 循环: 读老文件-写新文件 */
	while ((len = read(fd_old, buf, 1024)) > 0)
	{
		if (write(fd_new, buf, len) != len)
		{
			printf("can not write %s\n", argv[2]);
			return -1;
		}
	}

	/* 5. 关闭文件 */
	close(fd_old);
	close(fd_new);
	
	return 0;
}

(2)非通用函数:ioctl/mmap

在Linux中,还可以把一个文件的所有内容映射到内存,然后直接读写内存即可读写文件。(mmap)

示例:

实现文件的复制:

  • 打开老文件(open),确定老文件的大小(fstat→结构体stat)
  • 将老文件映射到stat.st_size大小的buff内存里(mmap)注:地址由内核分配,映射区域可被读取。
  • 创建新文件,并将buff写到新文件里。(open、write)
  • 最后关闭老文件和新文件(close)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>

/*
 * ./copy 1.txt 2.txt
 * argc    = 3
 * argv[0] = "./copy"
 * argv[1] = "1.txt"
 * argv[2] = "2.txt"
 */
int main(int argc, char **argv)
{
	int fd_old, fd_new;
	struct stat stat;
	char *buf;
	
	/* 1. 判断参数 */
	if (argc != 3) 
	{
		printf("Usage: %s <old-file> <new-file>\n", argv[0]);
		return -1;
	}

	/* 2. 打开老文件 */
	fd_old = open(argv[1], O_RDONLY);
	if (fd_old == -1)
	{
		printf("can not open file %s\n", argv[1]);
		return -1;
	}

	/* 3. 确定老文件的大小 */
	if (fstat(fd_old, &stat) == -1)
	{
		printf("can not get stat of file %s\n", argv[1]);
		return -1;
	}

	/* 4. 映射老文件 */
    //MAP_SHARD:写入映射区的数据会复制回文件,且运行其他映射文件的进程共享
	buf = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd_old, 0);
	if (buf == MAP_FAILED)
	{
		printf("can not mmap file %s\n", argv[1]);
		return -1;
	}

	/* 5. 创建新文件 */
	fd_new = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
	if (fd_new == -1)
	{
		printf("can not creat file %s\n", argv[2]);
		return -1;
	}

	/* 6. 写新文件 */
	if (write(fd_new, buf, stat.st_size) != stat.st_size)
	{
		printf("can not write %s\n", argv[2]);
		return -1;
	}

	/* 5. 关闭文件 */
	close(fd_old);
	close(fd_new);
	
	return 0;
}

(3)函数用法查询

怎么查询以上函数的用法呢?这里有三种方式,help、man、info。

最常用的方式是man,man手册既可以查看命令的用法,还可以查看函数的详细介绍。

man手册具体分为9大类:

以open函数为例,可以查看到头文件、了解到函数参数以及用法。

man 2 open

四、系统内核文件:

Linux系统调用如何进入内核模式?

用户态转到内核态,一般用swi和svc指令产生异常引入内核,并且传入参数让内核知道调用的是sys_open还是sys_read。这里有三种方式:(具体如图)

  • old ABI :是在swi命令的时候也传入参数
  • EABI:    先将参数放入R7寄存器里,后调用swi指令
  • ARM64:先将参数放入R8寄存器里,后调用svc指令

在内核中的文件是如何访问的呢?

进入内核后,先分辨文件的类型,然后根据不同的文件类型去找不同的设备驱动,继而进行读写或者输入输出控制。

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

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

相关文章

使用ChatGPT+MindShow一键生成PPT,以后再也不用担心制作PPT啦

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

深度学习及使用全连接神经网络实现手写数字识别案例开发

1.什么是深度学习和机器学习有什么区别&#xff1f;是什么原因使得部分问题机器学习无法解决需要深入研究深度学习&#xff1f; 人工智能、机器学习、深度学习的区别是什么&#xff1f;_哔哩哔哩_bilibili 深度学习是一种机器学习方法&#xff0c;它通过构建多层神经网络来实…

tmall.product.template.get( 产品接口 )

&#xffe5;免费必须用户授权 产品模板获取接口&#xff0c;对于非关键属性的类目&#xff0c;发布达尔文(监管)产品时&#xff0c;必须先根据类目获取产品模板。 产品模板定义产品发布需要的类目属性&#xff0c;包括&#xff1a; 关键属性:关键属性可以在类目上不存在。不…

spring的应用 xml配置实现定时任务

定时任务的实现&#xff1a; 通过xml实现&#xff1a; 创建qiuckstart的maven文件 把依赖配置改改 jdk1.8 以及12 再删掉一些不必要的配置 引入spring依赖坐标 和java同一个目录下创建resources 作为 资源根 结构如图&#xff1a; spring.xml配置&#xff1a; 从官网复制…

《JavaEE》网络中的基本概念

&#x1f451;作者主页&#xff1a;Java冰激凌 &#x1f4d6;专栏链接&#xff1a;JavaEE 局域网/广域网 在我们的生活中 经常会使用到网络 对于网络 我们现在已经变得与生活息息相关 甚至可以说为密不可分 而在我们的网络中 我们的网络是分为局域网与广域网 我们的局域网和广域…

【8086汇编】环境搭建 - 学习笔记:WIN10下安装配置 MASMPlus + DOSBox

【8086汇编】环境搭建 - 学习笔记&#xff1a;WIN10下安装配置 MASMPlus DOSBox 一、MASMPlus 1.2下载安装 二、DOSBox 0.74-3下载安装配置自动挂载C盘添加环境变量 三、masm v5.0四、ml.exe v6.11参考资料 一、MASMPlus 1.2 下载 脚本之家&#xff1a;MASMPlus(汇编开发环境…

【深度学习】第六阶段

1、超参数调试 在深度学习中&#xff0c;有各种各样的超参数&#xff0c;其中包括&#xff1a;学习率 α \alpha α、动量超参数 β \beta β、Adam中的超参数 β 1 \beta_1 β1​、 β 2 \beta_2 β2​和 ε \varepsilon ε、神经网络层数、每层的结点数量、 小样本数据集大小…

mlq color transfer: Color Transfer Using Probabilistic Moving Least Squares

文章目录 Color Transfer Using Probabilistic Moving Least Squares1. 颜色转换2. 如何计算匹配点的概率3. 核心思想和具体操作&#xff1a;4. 特征点覆盖不到的颜色4.1这里介绍一下引文7&#xff1a;4.2. 分析 5. Probabilistic Moving Least Squares with Spatial Constrain…

智能学习 | MATLAB实现ANT-BP多变量时间序列预测(蚁群算法优化BP神经网络)

智能学习 | MATLAB实现ANT-BP多变量时间序列预测(蚁群算法优化BP神经网络) 目录 智能学习 | MATLAB实现ANT-BP多变量时间序列预测(蚁群算法优化BP神经网络)预测效果基本介绍程序设计参考资料预测效果 基本介绍 MATLAB实现ANT-BP多变量时间序列预测(蚁群算法优化BP神经网络…

如何通过Bug跟踪管理,有效减少软件缺陷Bug?

1、Bug生命周期 Bug的生命周期是指从Bug被发现到被关闭的过程。一般的缺陷状态是&#xff1a;新建--指派--已解决--待验--关闭。如果待验的Bug没有解决&#xff0c;我们需要重新激活--指派--已解决&#xff0c;循环这个过程&#xff0c;中间还包括拒绝、延期等。 Bug跟踪管理 减…

设计模式:创建者模式 - 代理模式

文章目录 1.概述2.结构3.静态代理4.JDK动态代理5.CGLIB动态代理6.三种代理的对比7.优缺点8.使用场景 1.概述 由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时&#xff0c;访问对象不适合或者不能直接引用目标对象&#xff0c;代理对象作为访问对象和目标对象…

VUE3 学习笔记(八)引入 EasyUI for Vue

目录 一、什么是 EasyUI? 二、安装EasyUI for Vue3 1. 使用NPM安装 2. 导入EasyUI 三、安装完成出现问题解决 一、什么是 EasyUI? easyui是一个基于jQuery、Angular、Vue和React的用户界面组件的集合。easyui为构建现代的、交互式的、javascript应用程序提供了基本功能…

【历史上的今天】4 月 20 日:中国接入国际互联网;戴尔登顶 PC 市场;计算机先驱诞生日

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2023 年 4 月 20 日&#xff0c;在 2005 年的今天&#xff0c;CNET 网络公司宣布以 1100 万美元现金收购 PCHome 公司。根据当时的协议&#xff0c;PCHome 创始人将保留…

ManageEngine AD360:简化AD管理过程,提高组织安全性

Active Directory&#xff08;AD&#xff09;是微软提供的一种广泛使用的域管理工具&#xff0c;可以用于组织内部用户、计算机和其他资源的管理。尽管AD是一个强大的工具&#xff0c;但是它的管理不总是容易的&#xff0c;尤其是当需要处理大量的用户和计算机时&#xff0c;会…

linux下hive远程数据库模式安装

文章目录 前言1.安装mysql1&#xff09;使用yum安装2) 安装好启动服务3) 开启开机自动启动4) 修改权限4) 登录 2.Hive安装 Local/Embedded Metastore Database (Derby)1) 下载稳定版本解压即可2&#xff09;配置环境变量3) 配置远程连接mysql数据库4&#xff09;需要将mysql驱动…

Flink时间属性

1.概述 Flink支持三种与流数据处理相关的时间概念&#xff1a;Processing Time、Event Time和Ingestion Time。具体如下图所示&#xff1a; 当前Flink仅支持Processing Time和Event Time EventTime&#xff1a;您提供的事件时间&#xff08;通常是数据的最原始的创建时间&…

MongoDB 之 updateMany

MongoDB 之 updateMany 使用 https://www.mongodb.com/docs/v6.0/reference/operator/update/#update-operators db.collection.updateMany(<filter>,<update>,{upsert: <boolean>,writeConcern: <document>,collation: <document>,arrayFilters…

NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038

之前使用querydatabasetable处理器来获取mysql中的数据,我们只能写死一个sql的查询语句,但是 实际引用环境中,我们的一张mysql的表,可能有上千万的数据,那么,不可能,我们把sql查询语句写死,这样一次性如果获取所有数据,那么压力太大了,我们怎么弄呢?找了很久没有找到相关教程…

基于卷积神经网络的分类算法

基于卷积神经网络的分类算法 基于卷积神经网络的分类算法运行环境Python环境PyTorch环境Django环境数据预处理 基于卷积神经网络的分类算法 应用机器学习模型采用卷积神经网络&#xff0c;部署在Web环境中&#xff0c;通过Fashion-MNIST数据集进行模型训练和改进&#xff0c;实…

Scrum敏捷研发和项目管理

Scrum是全球运用最广泛的敏捷管理框架&#xff0c;Leangoo基于Scrum框架提供了一系列的流程和模板&#xff0c;可以帮助敏捷团队快速启动Scrum敏捷开发。 Leangoo完美支持Scrum敏捷框架&#xff0c;它提供了灵活的敏捷模板和极致的协作体验&#xff0c;可以让团队快速上手&am…