Linux 文件 I/O

news2024/10/5 11:57:29

1.Linux 应用编程中最基础的知识,即文件 I/O(Input、 Outout) , 文件 I/O 指的是对文件的输入/输出操作,说白了就是对文件的读写操作

Linux 下一切皆文件,文件作为 Linux 系统设计思想的核心理念,在 Linux 系统下显得尤为重要,所以对文件的 I/O 操作既是基础也是最重要的部分。

2.一个通用的 IO 模型通常包括打开文件、读写文件、关闭文件这些基本操作, 主要涉及到 4 个函数: open()、 read()、 write()以及 close()

一个简单地文件 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;
}

3.文件描述符

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

当调用 open 函数打开一个现有文件或创建一个新文件时,内核会向进程返回一个文件描述符, 用于指代被打开的文件,所有执行 IO 操作的系统调用都是通过文件描述符来索引到对应的文件,譬如示例代码

2.1.1 中,当调用 read/write 函数进行文件读写时,会将文件描述符传送给 read/write 函数, 所以在代码中,fb1 就是源文件 src_file 被打开时所对应的文件描述符, 而 fd2 则是目标文件 dest_file 被打开时所对应的文件描述符。

文件描述符是一种有限资源, 文件描述符是从 0 开始分配的,以此类推。

调用 open 函数打开文件的时候,分配的文件描述符一般都是从 3 开始,但是 0、 1、 2 这三个文件描述符已经默认被系统占用了,分别分配给了系统标准输入(0)、 标准输出(1)以及标准错误(2)。

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

4.open 打开文件

man 2 open #查看 open 函数的帮助信息

include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

pathname: 字符串类型,用于标识需要打开或创建的文件,可以包含路径(绝对路径或相对路径) 信息,譬如: "./src_file"(当前目录下的 src_file 文件)。

flags: 调用 open 函数时需要提供的标志, 包括文件访问模式标志以及其它文件相关标志,这些标志使用宏定义进行描述,都是常量, open 函数提供了非常多的标志,我们传入 flags 参数时既可以单独使用某一个标志,也可以通过位或运算(|) 将多个标志进行组合。

O_RDONLY 以只读方式打开文件
O_WRONLY 以只写方式打开文件
O_RDWR   以可读可写方式打开文件

mode: 此参数用于指定新建文件的访问权限,只有当 flags 参数中包含 O_CREAT 或 O_TMPFILE 标志时才有效(O_TMPFILE 标志用于创建一个临时文件)。

如果需要修改文件权限,可通过 chmod 命令对文件权限进行修改;

使用"ls -l"命令来查看到文件所对应的权限。

open 函数使用示例

(1)使用 open 函数打开一个已经存在的文件(例如当前目录下的 app.c 文件),使用只读方式打开

int fd = open("./app.c", O_RDONLY)
if (-1 == fd)
    return fd;

(2)使用 open 函数打开一个已经存在的文件(例如当前目录下的 app.c 文件),使用可读可写方式打开:

int fd = open("./app.c", O_RDWR)
if (-1 == fd)
    return fd;

(3)使用 open 函数打开一个指定的文件(譬如/home/dengtao/hello) , 使用可读可写方式,如果该文件是一个符号链接文件,则不对其进行解引用,直接返回错误:

int fd = open("/home/dengtao/hello", O_RDWR | O_NOFOLLOW);
if (-1 == fd)
    return fd;

(4)使用 open 函数打开一个指定的文件(譬如/home/dengtao/hello),如果该文件不存在则创建该文件,创建该文件时,将文件权限设置如下:

文件所属者拥有读、写、执行权限;

同组用户与其他用户只有读权限。

使用可读可写方式打开:

int fd = open("/home/dengtao/hello", O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);
if (-1 == fd)
    return fd;

5.write 写文件 --- 调用 write 函数可向打开的文件写入数据。

man 2 write

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

fd: 文件描述符。需要将进行写操作的文件所对应的文件描述符传递给 write 函数。

buf: 指定写入数据对应的缓冲区。

count: 指定写入的字节数。

返回值: 如果成功将返回写入的字节数(0 表示未写入任何字节),如果此数字小于 count 参数,这不

是错误,譬如磁盘空间已满,可能会发生这种情况;如果写入出错,则返回-1

6.read 读文件 --- 可从打开的文件中读取数据

man 2 read

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

fd: 文件描述符。与 write 函数的 fd 参数意义相同。

buf: 指定用于存储读取数据的缓冲区。

count: 指定需要读取的字节数。

返回值: 如果读取成功将返回读取到的字节数。

7.close 关闭文件 --- 关闭一个已经打开的文件

man 2 close

#include <unistd.h>
int close(int fd);

fd: 文件描述符,需要关闭的文件所对应的文件描述符。

返回值: 如果成功返回 0,如果失败则返回-1。

注:在我们的程序中打开了文件, 如果程序终止退出时没有关闭打开的文件,那么内核会自动将程序中打开的文件关闭。

7.

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

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

相关文章

java Lambda表达式引用类方法

Lambda表达式和方法引用是一对孪生兄弟 而引用类方法是Lambda支持的方法引用中的一种 引用类方法其实就是引用类的静态方法 直接上代码 首先 我们要创建一个包 包下创建一个接口 我这里叫subInterface 参考代码如下 public interface subInterface {int convelutl(String s…

【RabbitMQ】SpringBoot整合RabbitMQ

文章目录搭建初始环境引入依赖配置配置文件HelloWorld模型使用Work模型使用Fanout 广播模型Route 路由模型Topic 订阅模型(动态路由模型)搭建初始环境 引入依赖 <!--引入与rabbitmq集成依赖--> <dependency><groupId>org.springframework.boot</groupId…

NKOJ P3549 可见的点

分析 这道题乍一看是一道几何,实际上,是一道法雷数列模板题; 首先,他让我们求有多少条可见的线,实际上是让我们求有多少种不同的斜率可以存在,而斜率就是表现为yx\Large\frac{y}{x}xy​的形式;可以发现,只有当yx\Large\frac{y}{x}xy​为最简分数时,才能算作一条可见的线,其他…

Linux中如何使用Htop监控工具?【网络安全】

一、Htop界面展示 “Htop是一个用于Linux/Unix系统的交互式实时进程监控应用程序&#xff0c;也是top命令的替代品&#xff0c;它是所有Linux操作系统上预装的默认进程监控工具。 Htop还有许多其他用户友好的功能&#xff0c;这些功能在top命令下不可用 在Htop中&#xff0c;…

蓝桥杯省赛习题练习(二)

题目来源&#xff1a;2020年真题题集&#xff08;B组&#xff09; 注&#xff1a;代码都是自己写的&#xff0c;不是参考答案&#xff01; 目录1. 门牌制作运行结果2. 既约分数运行结果3. 蛇形填数运行结果4. 跑步锻炼运行结果5. 7段码6. 成绩统计运行结果7. 回文日期1. 门牌制…

5.9、TCP报文段的首部格式

为了实现可靠传输&#xff0c;TCP 采用了面向字节流\color{red}面向字节流面向字节流的方式。 但 TCP 在发送数据时&#xff0c;是从发送缓存取出一部分或全部字节并给其添加一个首部使之成为 TCP报文段\color{red}\texttt{TCP} 报文段TCP报文段后进行发送。 一个 TCP 报文段由…

ELAN设计理念:通过梯度路径分析设计网络设计策略

设计高效、高质量的表达性网络架构一直是深度学习领域最重要的研究课题。当今的大多数网络设计策略都集中于如何集成从不同层提取的特征&#xff0c;以及如何设计计算单元来有效地提取这些特征&#xff0c;从而增强网络的表现力。本文提出了一种新的网络设计策略&#xff0c;即…

Django框架MVT模型工作流程

Django 一、Django介绍 Django是一个开源的Web应用框架&#xff0c;由Python写成。采用了MTV的框架模式&#xff0c;它最初是被用来做CMS&#xff08;内容管理系统&#xff09;软件。 使用Django&#xff0c;程序员可以方便、快捷地创建高品质、易维护、数据库驱动的应用程序…

聚威新材在科创板被暂缓审议:毛利率高于同行,张天荣为董事长

2023年1月10日&#xff0c;上海证券交易所披露的信息显示&#xff0c;上海聚威新材料股份有限公司&#xff08;下称“聚威新材”&#xff09;被科创板上市委员会暂缓审议。据贝多财经了解&#xff0c;聚威新材仍有多个问题需进一步落实事项。 上市委要求聚威新材落实&#xff1…

YOLOv5进行水域游泳者检测系统源码+标注好的数据集

YoloV5对水域中游泳者进行检测 一、说明 1.1 项目说明 完整代码下载地址&#xff1a;YOLOv5进行水域游泳者检测系统源码标注好的数据集 本项目是使用 YoloV5 来训练自己的数据集&#xff0c;所以仅仅展示训练自定义数据集的过程。 本次视频检测的结果已经上传至B站&#x…

MATLAB-样条插值运算

MATLAB中不仅提供了一维插值、二维插值和三维插值方法&#xff0c;还提供了样条插值的方法。其主要思想是:假定有一组已知的数据点&#xff0c;希望找到该组数据的拟合多项式。在多项式的拟合过程中&#xff0c;对于每组相邻的样本数据点&#xff0c;存在一条曲线&#xff0c;该…

MCU-51:单片机之AD模数转换与DA数模转换

目录一、AD/DA介绍二、硬件电路模型2.1 模型2.2 硬件电路三、运算放大器3.1 运算放大器介绍3.2 运放电路四、DA原理4.1 T型电阻网络DA转换器&#xff1a;4.2 PWM型DA转换器&#xff1a;五、AD原理六、AD/DA性能指标七、XPT2046介绍7.1 功能说明7.2 XPT2046时序八、代码演示8.1 …

JAVA17连接sqlserver:驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接

JAVA17连接sqlserver报错 : com.microsoft.sqlserver.jdbc.SQLServerException: 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not accepted by client preferences [TLS13, TLS12]”。 Clien…

【Java寒假打卡】Java基础-字节输入流和字节输出流

【Java寒假打卡】Java基础-字节输入流和字节输出流&#xff09;概述字节输出流快速入门字节输出流的注意事项输出字节流-一次性写多个数据字节输出流的两个问题try-catch-finally捕获异常字节输入流写数据字节流读数据 一次性读取多个数据案例、文件复制使用字节数组进行拷贝文…

基于Springboot+vue+uni-app的校园失物招领平台源码+数据库,含主体PC端、微信小程序和web后台数据管理平台

校园失物招领网站 | lijinghai 项目介绍 &#x1f4d6; &#x1f449;基于Springbootvueuni-app的校园失物招领平台. 含平台主体PC端、微信小程序和web后台数据管理平台. 完整代码下载地址&#xff1a;基于Springbootvueuni-app的校园失物招领平台源码数据库 失物招领信息一…

枚举算法实例应用(二)

枚举算法实例应用&#xff08;二&#xff09; Extended Lights Out Description In an extended version of the game Lights Out, is a puzzle with 5 rows of 6 buttons each (the actual puzzle has 5 rows of 5 buttons each). Each button has a light. When a button …

什么是云原生(非常详细)

云原生计算加速了应用与基础设施资源之间的解耦&#xff0c;通过定义开放标准&#xff0c;向下封装资源&#xff0c;将复杂性下沉到基础设施层&#xff1b;向上支撑应用&#xff0c;让开发者更关注业务价值。此外&#xff0c;云原生计算提供统一的技术栈&#xff0c;动态、混合…

LabVIEW创建Web服务

LabVIEW创建Web服务在LabVIEW项目中开发Web服务&#xff0c;组合并配置构成Web服务的VI和其他文件。按照下列步骤创建一个Web服务项目和两个HTTP方法VI。创建一个组织Web服务文件的LabVIEW项目。将项目保存为Tutorial.lvproj。右键单击我的电脑并选择新建Web服务。LabVIEW在该终…

C语言基本数据类型

一、float、double和 long double 1.1 声明浮点型变量 1.2浮点型常量 1.3 打印浮点值 二、复数和虚数类型 三、其他类型 一、float、double和 long double 对于金融和数学的程序经常使用浮点数&#xff0c;而C语言中的浮点类型有float、double和 long double类型。常见的…

CentOS Stream 9下RabbitMQ安装教程(最新RabbitMQ安装教程)

CentOS Stream 9 RabbitMQ安装教程前言Erlang下载安装RabbitMQ下载安装启动RabbitMQ配置RabbitMQManagement Plugin访问和权限日志文件和管理总结和收获如果博主的文章对您有所帮助&#xff0c;可以评论、点赞、收藏&#xff0c;支持一下博主!!!前言 操作系统&#xff1a;Cent…