【linuxC语言】系统调用IO文件操作

文章目录

  • 前言
  • 一、文件描述符介绍
  • 二、系统调用IO API介绍
    • 2.1 open函数
    • 2.2 close函数
    • 2.3 read函数
    • 2.4 write函数
    • 2.5 lseek函数
  • 三、示例代码
  • 总结


前言

在Linux系统中,C语言通过系统调用实现对文件的输入输出(I/O)操作。系统调用提供了访问操作系统核心功能的接口,其中包括文件的创建、读取、写入和关闭等操作。这篇文章将介绍在Linux环境下,如何利用C语言进行基本的文件操作,通过系统调用实现对文件的有效管理。


一、文件描述符介绍

在Linux中,文件描述符是一个用来标识打开文件或者其他I/O资源的整数。每当你打开一个文件、网络连接或者其他的I/O资源时,Linux内核会分配一个唯一的文件描述符来标识这个资源。

文件描述符的作用很重要,因为它允许程序访问和操作打开的文件或者其他I/O资源。通过文件描述符,程序可以读取、写入、关闭以及对文件进行其他操作,比如移动文件指针。文件描述符也被用来进行进程间通信,比如通过管道或者套接字。

在Linux中,标准输入、标准输出和标准错误输出也分别有对应的文件描述符,它们分别是0、1和2。这意味着你可以把标准输出重定向到一个文件,或者把标准错误输出发送到另一个程序,这些都是通过文件描述符来完成的。总之,文件描述符在Linux系统中扮演着非常重要的角色,是程序与文件系统和其他I/O资源进行交互的桥梁。

二、系统调用IO API介绍

在使用系统调用IO之前我们需要加上下面这些头文件:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

2.1 open函数

open函数原型如下:

int open(const char *pathname, int flags);

参数1为打开文件的位置,他可以打开文件还可以打开一个设备device
参数2为一个类似于权限设置的一个标识,他有如下取值:
O_RDONLY:只读方式打开文件。
O_WRONLY:只写方式打开文件。
O_RDWR:读写方式打开文件。
O_CREAT:如果文件不存在,则创建一个新文件。
O_TRUNC:如果文件存在,将其长度截断为0。
O_APPEND:在文件末尾追加写入数据,而不是覆盖文件内容。
O_EXCL:与 O_CREAT 一起使用,如果文件存在则返回错误。
O_NONBLOCK:以非阻塞方式打开文件。
O_SYNC:在每次写操作之后立即将数据写入磁盘,确保数据同步。
这些参数可以单独使用,也可以通过按位或 | 连接

他的返回值为文件描述符,类型为int

2.2 close函数

close用于关闭一个文件描述符
他的函数原型如下:

int close(int fd);

参数为文件描述符
close 返回 0 表示 成功 , 或者 -1 表示 有 错误 发生 .

2.3 read函数

read函数原型如下:

ssize_t read(int fd, void *buf, size_t count);

函数 read() 用于从文件描述符 fd 指定的文件中读取数据,并将读取的数据存储到 buf 指向的内存空间中,最多读取 count 字节的数据。该函数的参数和返回值如下:

fd:要读取数据的文件描述符。
buf:指向存储读取数据的缓冲区的指针。
count:要读取的最大字节数。
返回值是 ssize_t 类型,表示读取的字节数。如果读取成功,则返回实际读取的字节数;如果到达文件末尾,返回值为0;如果发生错误,返回值为-1,并设置全局变量 errno 来指示发生的错误类型。

2.4 write函数

write函数原型如下:

ssize_t write(int fd, const void *buf, size_t count);

函数 write() 用于将数据从内存中的 buf 写入到文件描述符 fd 所指定的文件中,最多写入 count 字节的数据。该函数的参数和返回值如下:

fd:要写入数据的文件描述符。
buf:指向包含要写入数据的缓冲区的指针。
count:要写入的字节数。
返回值是 ssize_t 类型,表示实际写入的字节数。如果写入成功,则返回写入的字节数;如果发生错误,返回值为-1,并设置全局变量 errno 来指示错误类型。

需要注意的是,write() 函数不保证一次性写入所有请求的字节数,它可能写入部分数据,而不是全部。在实际应用中,我们通常需要在返回值不等于请求写入的字节数时进行额外的处理。

2.5 lseek函数

lseek函数原型如下:

off_t lseek(int fd, off_t offset, int whence);

fd:要设置偏移量的文件描述符。
offset:要移动的偏移量,可以为正数、负数或零。正数表示向文件尾方向移动,负数表示向文件头方向移动,零表示从文件开头计算的绝对偏移量。
whence:指定偏移量的计算方式,可以是以下几个值之一:
SEEK_SET:偏移量相对于文件开头计算。
SEEK_CUR:偏移量相对于当前位置计算。
SEEK_END:偏移量相对于文件末尾计算。
返回值是 off_t 类型,表示设置后的文件偏移量。如果设置成功,则返回新的偏移量;如果发生错误,返回值为-1,并设置全局变量 errno 来指示错误类型。

三、示例代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#define BUFFER_SIZE 1024

int main() {
    int fd;
    ssize_t bytes_written, bytes_read;
    off_t offset;
    char buffer[BUFFER_SIZE];

    // 打开文件
    fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    // 写入数据到文件
    const char *data_to_write = "Hello, World!";
    bytes_written = write(fd, data_to_write, strlen(data_to_write));
    if (bytes_written == -1) {
        perror("write");
        exit(EXIT_FAILURE);
    }
    printf("Bytes written: %ld\n", bytes_written);

    // 设置文件偏移量
    offset = lseek(fd, 0, SEEK_SET);
    if (offset == -1) {
        perror("lseek");
        exit(EXIT_FAILURE);
    }

    // 读取文件数据
    bytes_read = read(fd, buffer, BUFFER_SIZE);
    if (bytes_read == -1) {
        perror("read");
        exit(EXIT_FAILURE);
    }
    printf("Bytes read: %ld\n", bytes_read);
    printf("Data read: %.*s\n", (int)bytes_read, buffer);

    // 关闭文件
    if (close(fd) == -1) {
        perror("close");
        exit(EXIT_FAILURE);
    }

    return 0;
}

在这里插入图片描述


总结

通过系统调用进行文件I/O操作是Linux C编程中的关键方面。我们了解了如何使用系统调用来创建文件、读取文件内容、写入数据,并最终关闭文件。这些基本的文件操作是构建更复杂应用程序的基础。通过合理地利用系统调用,我们能够更好地掌控文件资源,实现高效、稳定的文件处理。在深入学习C语言和Linux编程的过程中,对文件I/O的理解将成为编写强大、可靠程序的不可或缺的一部分。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLM - 使用 Langchain 实现本地 Naive RAG

目录 一.引言 二.构建本地 Langchain 库 1.Doc 知识文档 2.Split 文档切分 3.Encode 内容编码 4.Similar 本地库构建 三.缓存本地 Langchain 库 四.读取本地 Langchain 库 1.Load 读取缓存 2.Similar 预测 3.Add 添加文档 五.总结 一.引言 上一篇博客介绍了当下 R…

M2TS转MP4怎么转?超快的方法~

M2TS格式的优点主要体现在对高清视频的完美支持&#xff0c;能够提供极致的视觉体验。然而&#xff0c;由于其相对较大的文件大小&#xff0c;有时可能不太适合网络传输。此外&#xff0c;部分不支持M2TS的播放设备可能导致一定的兼容性问题。 想要播放m2ts视频&#xff0c;可…

MySQL实战45讲——30答疑文章(二):用动态的观点看加锁

目录 不等号条件里的等值查询 等值查询的过程 怎么看死锁&#xff1f; 怎么看锁等待&#xff1f; update 的例子 小结 上期问题时间 提示 文章摘自林晓斌老师《MySQL实战45讲》&#xff0c;作为笔记而用&#xff0c;故有加一些自己的理解。在第[20]和[21]篇文章中&…

Python基础二

一、变量 在编程中&#xff0c;变量是用来存储数据值的名称。在 Python 中&#xff0c;变量是动态类型的&#xff0c;这意味着你可以将任何类型的数据分配给一个变量&#xff0c;而不需要提前声明变量的类型。 1、全局变量 在函数外部定义的变量是全局变量&#xff0c;可以在程…

cesium-天际线

主要是两个着色器 let postProccessStage new Cesium.PostProcessStage({//unform着色器对象 textureScalefragmentShader:// 声明一个纹理采样器 colorTexture 用于读取纹理颜色uniform sampler2D colorTexture; // 声明一个纹理采样器 depthTexture 用于读取深度纹理unifor…

Python接口自动化之Token详解及应用

以下介绍Token原理及在自动化中的应用。 一、Token基本概念及原理 1.Token作用 为了验证用户登录情况以及减轻服务器的压力&#xff0c;减少频繁的查询数据库&#xff0c;使服务器更加健壮。 2.什么是Token Token是服务端生成的一串字符串&#xff0c;以作客户端进行请求的…

《焦点访谈》上的星火大模型:AI生成春天散文,共绘美好春天

发布 | 大力财经 在今年的全国“两会”上&#xff0c;全国人大代表、科大讯飞董事长刘庆峰提出了关于制定国家《通用人工智能发展规划》的建议&#xff0c;推动我国通用人工智能的发展&#xff0c;以应对全球AI领域的激烈竞争。 刘庆峰在3月6日晚间的《焦点访谈》中表示&#…

简单整理vue-router,路由知识

1.项目中引入 1.1 安装注册 1.2 封装抽离 在main.js中 书写,会造成单个js文件过于臃肿的情况,需要将路由配置部分抽离出来,在src下新建router文件夹,新建index.js文件 import Vue from vue import VueRouter from vue-router import HomeView from ../views/HomeView.vue im…

Elasticsearch:dense vector 数据类型及标量量化

密集向量&#xff08;dense_vector&#xff09;字段类型存储数值的密集向量。 密集向量场主要用于 k 最近邻 (kNN) 搜索。 dense_vector 类型不支持聚合或排序。 默认情况下&#xff0c;你可以基于 element_type 添加一个 dend_vector 字段作为 float 数值数组&#xff1a; …

【中间件】docker的安装

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;中间件 ⛺️稳中求进&#xff0c;晒太阳 .卸载旧版 首先如果系统中已经存在旧的Docker&#xff0c;则先卸载&#xff1a; yum remove docker \docker-client \docker-client-latest \doc…

Web自动化测试学习方向(Selenium)

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

chrome插件webRequest拦截请求并获取post请求体requestBody数据raw内容,解决中文乱码问题

详细使用说明可以看官方文档&#xff1a;https://developer.chrome.com/docs/extensions/reference/api/webRequest?hlzh-cn 拦截操作 想要通过浏览器插件拦截请求的话&#xff0c;需要在manifest.json里面添加webRequet权限&#xff1a; 拦截请求代码放在background.js里面…

Web服务器

Web服务器 1. 阻塞/非阻塞、同步/异步(网络IO)2. Unix/Linux 上的五种IO模型2.1 阻塞 blocking2.2 非阻塞 non-blocking &#xff08;NIO&#xff09;2.3 IO复用&#xff08;IO multiplexing&#xff09;2.4 信号驱动&#xff08;signal-driven&#xff09;2.5 异步&#xff08…

【项目实践04】【RocketMQ消息收发拦截器】

文章目录 一、前言二、项目背景三、实现方案1. 关键接口2. 消息发送方3. 消息消费方4. 配置引入类5. 使用示例 四、思路扩展1. 消费流程简介 一、前言 本系列用来记录一些在实际项目中的小东西&#xff0c;并记录在过程中想到一些小东西&#xff0c;因为是随笔记录&#xff0c…

【Web】浅聊JDBC的SPI机制是怎么实现的——DriverManager

目录 前言 分析 前言 【Web】浅浅地聊JDBC java.sql.Driver的SPI后门-CSDN博客 上篇文章我们做到了知其然&#xff0c;知道了JDBC有SPI机制&#xff0c;并且可以利用其Driver后门 这篇文章希望可以做到知其所以然&#xff0c;对JDBC的SPI机制的来源做到心里有数 分析 先是…

如何实现数据中心布线变更管理?

前言 随着科技的不断发展&#xff0c;数据中心作为企业的核心基础设施之一&#xff0c;承载着大量重要的业务数据。在数据中心运维过程中&#xff0c;变更管理流程变得尤为重要&#xff0c;它是确保数据中心基础设施稳定运行和保障数据安全的关键环节。变更管理的定义是指在维…

电商效果图云渲染优势是什么?

电商效果图云渲染指的是利用云计算技术&#xff0c;将电商所需的效果图渲染任务转移至云服务器进行处理。这些云服务器凭借其卓越的计算能力与庞大的存储空间&#xff0c;能够迅速完成复杂的渲染任务&#xff0c;从而释放本地电脑资源&#xff0c;提升工作效率。 电商效果图云…

常见四种限流算法详解(附:javaDemo)

限流简介 现代互联网很多业务场景&#xff0c;比如秒杀、下单、查询商品详情&#xff0c;最大特点就是高并发&#xff0c;而往往我们的系统不能承受这么大的流量&#xff0c;继而产生了很多的应对措施&#xff1a;CDN、消息队列、多级缓存、异地多活。 但是无论如何优化&…

今日学习总结2024.3.2

最近的学习状态比较好&#xff0c;感觉非常享受知识进入脑子的过程&#xff0c;有点上头。 实验室一个星期唯一一天的假期周六&#xff0c;也就是今天&#xff0c;也完全不想放假出去玩啊&#xff0c;在实验室泡了一天。 很后悔之前胆小&#xff0c;没有提前投简历找实习&…

基于毕奥-萨伐尔定律的交流电机的4极旋转磁场matlab模拟与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于毕奥-萨伐尔定律的交流电机的4极旋转磁场&#xff0c;对比不同定子半径&#xff0c;对比2级旋转磁场。 2.系统仿真结果 3.核心程序与模型 版本&#xff1a;MATLAB2022a…