Linux文件IO-基础知识了解及文件描述符

1、简介

本章给大家介绍 Linux 应用编程中最基础的知识,即文件 I/O(Input、Outout),文件 I/O 指的是对文件的输入/输出操作,说白了就是对文件的读写操作;Linux 下一切皆文件,文件作为 Linux 系统设计思想的核心理念,在 Linux 系统下显得尤为重要,所以对文件的 I/O 操作既是基础也是最重要的部分。 本章将向大家介绍 Linux 系统下文件描述符的概念,随后会逐一讲解构成通用 I/O 模型的系统调用,譬如打开文件、关闭文件、从文件中读取数据和向文件中写入数据以及这些系统调用涉及的参数等内容。 本章将会讨论如下主题内容。

  • 文件描述符的概念;
  • 打开文件 open()、关闭文件 close();
  • 写文件 write()、读文件 read();
  • 文件读写位置偏移量。

2、一个简单的文件IO示例

本章主要介绍文件 IO 操作相关系统调用,一个通用的 IO 模型通常包括打开文件、读写文件、关闭文件这些基本操作,主要涉及到 4 个函数:open()、read()、write()以及 close(),我们先来看一个简单地文件读写示例,应用程序代码如下所示:

示例代码 2.1.1 一个简单地文件 IO 示例

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(void) {char buff[1024];int fd1, fd2;int ret;/* 打开源文件 src_file(只读方式) */fd1 = open("./src_file", O_RDONLY);if (-1 == fd1)return fd1;/* 打开目标文件 dest_file(只写方式) */fd2 = open("./dest_file", O_WRONLY);if (-1 == fd2) {ret = fd2;goto out1;}/* 读取源文件 1KB 数据到 buff 中 */ret = read(fd1, buff, sizeof(buff));if (-1 == ret)goto out2;/* 将 buff 中的数据写入目标文件 */ret = write(fd2, buff, sizeof(buff));if (-1 == ret)goto out2;ret = 0;out2:/* 关闭目标文件 */close(fd2);out1:/* 关闭源文件 */close(fd1);return ret;
}

这段代码非常简单明了,代码所要实现的功能在注释当中已经描述得很清楚了,从源文件 src_file 中读取 1KB 数据,然后将其写入到目标文件 dest_file 中(这里假设当前目录下这两个文件都是存在的);在进行读写操作之前,首先调用 open 函数将源文件和目标文件打开,成功打开之后再调用 read 函数从源文件中读取 1KB 数据,然后再调用 write 函数将这 1KB 数据写入到目标文件中,至此,文件读写操作就完成了,读写操作完成之后,最后调用 close 函数关闭源文件和目标文件。

3、文件描述符

调用 open 函数会有一个返回值,譬如示例代码 2.1.1 中的 fd1 和 fd2,这是一个 int 类型的数据,在 open函数执行成功的情况下,会返回一个非负整数,该返回值就是一个文件描述符(file descriptor),这说明文件描述符是一个非负整数;对于 Linux 内核而言,所有打开的文件都会通过文件描述符进行索引。

当调用 open 函数打开一个现有文件或创建一个新文件时,内核会向进程返回一个文件描述符,用于指代被打开的文件,所有执行 IO 操作的系统调用都是通过文件描述符来索引到对应的文件,譬如示例代码2.1.1 中,当调用 read/write 函数进行文件读写时,会将文件描述符传送给 read/write 函数,所以在代码中,fd1 就是源文件 src_file 被打开时所对应的文件描述符,而 fd2 则是目标文件 dest_file 被打开时所对应的文件描述符。

一个进程可以打开多个文件,但是在 Linux 系统中,一个进程可以打开的文件数是有限制,并不是可以无限制打开很多的文件,大家想一想便可以知道,打开的文件是需要占用内存资源的,文件越大、打开的文件越多那占用的内存就越多,必然会对整个系统造成很大的影响,如果超过进程可打开的最大文件数限制,内核将会发送警告信号给对应的进程,然后结束进程;在 Linux 系统下,我们可以通过 ulimit 命令来查看进程可打开的最大文件数,用法如下所示:


ulimit -n 

图 2.2.1 查看进程可打开的最大文件数

该最大值默认情况下是 1024,也就意味着一个进程最多可以打开 1024 个文件,当然这个限制数其实是可以设置的,这个就先不给大家介绍了,当然除了进程有最大文件数限制外,其实对于整个 Linux 系统来说,也有最大限制,那么关于这些问题,如果后面的章节内容中涉及到了再给大家进行介绍。

所以对于一个进程来说,文件描述符是一种有限资源,文件描述符是从 0 开始分配的,譬如说进程中第一个被打开的文件对应的文件描述符是 0、第二个文件是 1、第三个文件是 2、第 4 个文件是 3……以此类推,所以由此可知,文件描述符数字最大值为 1023(0~1023)。每一个被打开的文件在同一个进程中都有一个唯一的文件描述符,不会重复,如果文件被关闭后,它对应的文件描述符将会被释放,那么这个文件描述符将可以再次分配给其它打开的文件、与对应的文件绑定起来。

每次给打开的文件分配文件描述符都是从最小的没有被使用的文件描述符(0~1023)开始,当之前打开的文件被关闭之后,那么它对应的文件描述符会被释放,释放之后也就成为了一个没有被使用的文件描述符了。

当我们在程序中,调用 open 函数打开文件的时候,分配的文件描述符一般都是从 3 开始,这里大家可能要问了,上面不是说从 0 开始的吗,确实是如此,但是 0、1、2 这三个文件描述符已经默认被系统占用了,分别分配给了

系统标准输入(0)

标准输出(1)

以及标准错误(2)

关于这个问题,这里不便给大家说太多,毕竟这是后面的内容,这里只是给大家提一下,后面遇到了再具体讲解。

Tips:Linux 系统下,一切皆文件,也包括各种硬件设备,使用 open 函数打开任何文件成功情况下便会返回对应的文件描述符 fd。每一个硬件设备都会对应于 Linux 系统下的某一个文件,把这类文件称为设备文件。所以设备文件对应的其实是某一硬件设备,应用程序通过对设备文件进行读写等操作、来使用、操控硬件设备,譬如 LCD 显示器、串口、音频、键盘等。

  • 标准输入一般对应的是键盘,可以理解为 0 便是打开键盘对应的设备文件时所得到的文件描述符;
  • 标准输出一般指的是 LCD 显示器,可以理解为 1 便是打开 LCD 设备对应的设备文件时所得到的文件描述符;
  • 标准错误一般指的也是 LCD 显示器。

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

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

相关文章

付费流量如何有效撬动自然流?

付费流量能够有效撬动自然流量的情况主要有三种。 首先&#xff0c;当直播刚开始时&#xff0c;流量通常较为泛化&#xff0c;转化效果不理想。在这种情况下&#xff0c;借助付费流量圈选精准受众&#xff0c;可以显著提高转化率。一旦形成转化&#xff0c;系统会根据这些转化行…

怎么使用Chrome与C++实现高效自动化测试

在软件开发过程中&#xff0c;自动化测试是确保代码质量和稳定性的关键步骤。谷歌浏览器&#xff08;Chrome&#xff09;提供了强大的开发者工具和丰富的API&#xff0c;结合C的强大功能&#xff0c;可以实现高效的自动化测试。本文将介绍如何使用Chrome和C来实现这一目标。&am…

vue2使用npm引入依赖(例如axios),报错Module parse failed: Unexpected token解决方案

报错情况 Module parse failed: Unexpected token (5:2) You may need an appropriate loader to handle this file type. 原因 因为我们npm install时默认都是下载最新版本&#xff0c;然后个别依赖的版本太新&#xff0c;vue2他受不起这个福分。 解决方法 先去package.js…

Rasa对话模型——做一个语言助手

1、Rasa模型 1.1 模型介绍 Rasa是一个用于构建对话 AI 的开源框架&#xff0c;主要用于开发聊天机器人和语音助手。Rasa 提供了自然语言理解&#xff08;NLU&#xff09;和对话管理&#xff08;DM&#xff09;功能&#xff0c;使开发者能够创建智能、交互式的对话系统。 1.2…

数据驱动新时代:数据飞轮如何唤醒中台潜能

前言 随着数字化转型浪潮的不断高涨&#xff0c;数据已跃升为企业战略蓝图中不可或缺的核心资产。为了更有效地整合与利用来自内外部的海量数据资源&#xff0c;众多企业纷纷着手构建数据中台&#xff0c;以期实现数据的集中管理、高效共享以及基于数据的精准业务决策。然而&a…

低代码开发平台系统架构概述

概述 织信低代码开发平台&#xff08;产品全称&#xff1a;织信Informat&#xff09;是一款集成了应用设计、运行与管理的综合性平台。它提供了丰富的功能模块&#xff0c;帮助用户快速构建、部署和维护应用程序。织信低代码平台通过集成丰富的功能模块&#xff0c;为用户提供…

构建 LLM 应用程序时经常遇到的高级概念的快速指南

使用案例 数据支持的 LLM 应用程序有无数的用例&#xff0c;但大致可以分为四类&#xff1a; 结构化数据提取 Pydantic 提取器允许您指定要从数据中提取的精确数据结构&#xff0c;并使用 LLM 以类型安全的方式填充缺失的部分。这对于从 PDF、网站等非结构化来源中提取结构化…

cdr怎么画虚线?

虚线是以点或者短线画成的断续的线&#xff0c;多用于几何图形或者标记。我们在平常学习工作中经常使用标记的方式。根据国标制图规定 机械制图 图样画法 图线规定&#xff0c;技术图样中&#xff0c;主要使用细虚线和粗虚线两种&#xff0c;细虚线用以表示不可见棱边线和不可见…

使用高版本nodej报错:node: /lib64/libm.so.6: version `GLIBC_2.27‘ not found

如果要更新GLIBC_2.27会很繁琐&#xff0c;且耗时较长&#xff0c;所以建议下载带glibc的版本的nodejs 解决方案&#xff1a;下载带glibc的版本安装&#xff0c;如果是使用nvm则解压到对应的版本控制路径 我使用的版本是v20.16.0&#xff1a;Index of /download/release/v20.1…

apk反编译修改教程系列-----修改apk 去除软件加固状态 实例操作步骤解析_1【二十七】

上期博文我们基本了解了apk的一些加固方面的常识。了解了加固的一些手段与 列举了加固检测的方法。其实对于初学者来说。这些常识了解一下即可。具体还是要实际应用。今天将陆续以实例操作来演示有些apk应用去加固的步骤。尽量步骤详细到每一步方便对照操作。 通过博文了解 1…

SD-WAN如何保障企业数据安全?

SD-WAN&#xff08;软件定义广域网&#xff09;作为一种现代化网络解决方案&#xff0c;不仅能够优化和管理广域网的连接&#xff0c;还集成了一系列安全功能&#xff0c;帮助企业保护其数据安全。以下将详细介绍SD-WAN如何有效保障企业数据安全的机制。 在采用SD-WAN技术之前&…

杭州等保测评揭秘:数据安全如何成为企业的“一道锁”

在数字化时代&#xff0c;数据安全已成为企业和机构面临的重要挑战。杭州作为科技创新的前沿城市&#xff0c;积极推进信息安全建设&#xff0c;其中等保测评&#xff08;等级保护测评&#xff09;成为保障数据安全的重要手段。 等保测评是依据《信息安全等级保护管理办法》对…

进程的重要函数

进程的重要函数: fork函数 了解fork函数 通过调用fork()函数&#xff0c;则会产生一个新的进程。调用fork()函数的进程叫做 父进程&#xff0c;产生的新进程则为子进程。 其编码过程: 1.函数功能: 函数头文件 #include <sys/types.h> #include <unistd.h> 函数…

AI绘画Stable Diffusion 自制素材工具: layerdiffusion插件—你的透明背景图片生成工具

大家好&#xff0c;我是灵魂画师向阳 今天给大家分享一款AI绘画的神级插件—LayerDiffusion。 Layerdiffusion是一个用于stable-diffusion-webui 的透明背景生成&#xff08;不是生成图再工具扣图&#xff0c;是直接生成透明背景透明图像&#xff09;插件扩展&#xff0c;它可…

C++ STL全面解析:六大核心组件之一----迭代器(STL进阶学习)

目录 迭代器&#xff08;iterator&#xff09; 迭代器的分类 迭代器的使用 创建迭代器 迭代器的基本操作 使用迭代器遍历容器 迭代器的有效性和安全性 迭代器的类型 迭代器与算法 迭代器设计思维 迭代器的本质 文件 mylist-iter.h 文件 mylist-iter-test.cpp 迭代…

多线程学习篇三:共享带来的问题及解决方案

1. 共享带来的问题 1.1 案例演示 两个线程对初始值为 0 的静态变量一个做自增&#xff0c;一个做自减&#xff0c;各做 5000 次&#xff0c;结果是 0 吗&#xff1f; Slf4j(topic "c.Sync01") public class Sync01 {private static int COUNTER 0;public static…

一次渲染十万条数据:前端技术优化(上)

今天看了一篇文章&#xff0c;写的是一次性渲染十万条数据的方法&#xff0c;本文内容是对这篇文章的学习总结&#xff0c;以及知识点补充。 在现代Web应用中&#xff0c;前端经常需要处理大量的数据展示&#xff0c;例如用户评论、商品列表等。直接渲染大量数据会导致浏览器性…

【C++登堂入室】类和对象(下)

目录 一、 再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1.3 explicit关键字 二、static成员 2.1 概念 2.2 特性 三、友元函数 3.1 友元函数 3.2 友元类 四、内部类 五、 再次理解类和对象 结尾 一、 再谈构造函数 1.1 构造函数体赋值 在创建对象时&#xf…

【C++】多态的认识和理解

个人主页 文章目录 ⭐一、多态的概念&#x1f384;二、多态的定义及实现1.多态的构成2.实现多态的条件3.虚函数的概念4.虚函数的重写和覆盖5.析构函数的重写6.协变7.override和 final关键字8.重载、重写/覆盖、隐藏这三者的区别 &#x1f3e0;三、纯虚函数和抽象类的关系&#…

三目运算及简单案例

//三目运算是用来简化判断的 //所谓的三目 有三个表达式组成 //表达式一 条件表达式 返回的结果是布尔 //表达式二 条件表达式结果为true 时 返回的结果 //表达式三 条件表达式结果为false 时 返回的值 int age 20; //获取用…