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

news2025/1/13 17:44:15

文章目录

  • 前言
  • 一、文件描述符介绍
  • 二、系统调用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的理解将成为编写强大、可靠程序的不可或缺的一部分。

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

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

相关文章

Windows下JDK下载、配置Java环境变量配置及多个JDK使用

Windows下JDK下载、配置Java环境变量配置及多个JDK使用 1. Windows下配置Java-JDK环境变量 1.1 下载Windows版本JDK 下载地址&#xff1a;(https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) 1.2 Windows下安装JDK 双击进行安装 下一步&#xf…

SpringCloud 服务的注册与发现

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅&#xff0c;从传统的模块之间调用&#xff0c;一步步的升级为 SpringCloud 模块之间的调用&#xff0c;此篇文章为第二篇&#xff0c;即使用服务注册和发现的组件&#xff0c;此篇文章会介绍 Eureka、Zookeeper 和 Consu…

ZYNQ linux笔记 --- Linux UIO框架下调用HLS ip核

目标 编写了 HLS IP核,实现对图像的缩放,已通过HLS 仿真验证和裸机验证,想在Linux端调用该IP 工程构建 简单描述一下,vdma出来连接 resize ip核,resize ip核后面接 vid_out ip resize ip核的 interrput 接口通过 xlconcat ip 连接到PS端中断接口IRQ,这一点很重要! 导…

透视和仿射变换的区别

仿射变换矩阵通常是2x3的矩阵。 三个特点&#xff1a; 直线依然是直线平行线依然平行 [ x ′ y ′ 1 ] [ a 11 a 12 b 1 a 21 a 22 b 2 0 0 1 ] [ x y 1 ] x ′ a 11 ∗ x a 12 ∗ y b 1 y ′ a 21 ∗ x a 22 ∗ y b 2 \begin{gathered} \begin{bmatrix}x\\y\\1\end{b…

2023年全国职业院校技能大赛 GZ073网络系统管理赛项 模块A:网络构建(运维配置)

1.完成整网连通后,进入网络监控运维阶段,运维软件已安装在PC的虚拟机中,通过运维平台监控拓扑中所有网络设备(AP除外)。考试现场提供运维平台登陆的用户名密码信息。 2.通过运维平台将被监控设备纳入监控范围;通过拓扑配置功能,将网络拓扑配置到平台中。

【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测

视觉AIGC识别——人脸伪造检测、误差特征 不可见水印 前言视觉AIGC识别【误差特征】DIRE for Diffusion-Generated Image Detection方法扩散模型的角色DIRE作为检测指标 实验结果泛化能力和抗扰动 人脸伪造监测&#xff08;Face Forgery Detection&#xff09;人脸伪造图生成 …

【Python】成功解决TypeError: ‘float‘ object is not iterable

【Python】成功解决TypeError: ‘float’ object is not iterable &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得…

为什么桌面领域没有一款 Linux 或 UNIX 能与 Windows 鼎足而立?

为什么桌面领域没有一款 Linux 或 UNIX 能与 Windows 鼎足而立&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Linux 的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享…

大数据揭秘!不得不提的企业数据查询的隐藏宝藏平台。

在现代社会&#xff0c;企业数据已经成为了衡量一个公司实力、潜力以及未来走势的重要指标之一。对于投资者、分析师和企业家来说&#xff0c;获取这些数据并进行深度分析显得尤为重要。那么&#xff0c;如何查询到企业的数据呢&#xff1f;本文将为您介绍一些可以查询企业数据…

sql server使用逗号,分隔保存多个id的一些查询保存

方案一&#xff0c;前后不附加逗号&#xff1a; 方案二&#xff0c;前后附加逗号&#xff1a; 其他保存方案&#xff1a; &#xff08;这里是我做一个程序的商家日期规则搞得&#xff0c;后面再补具体操作&#xff09;&#xff1a; 1,2,3 | 1,2,3 | 1,2,3; 1,2,3 &#xff1…

尤雨溪:Vue 未来展望新的一轮

十年&#xff0c;一个既漫长又短暂的时光跨度&#xff0c;对于技术世界来说&#xff0c;更是沧海桑田的瞬间。在这十年里&#xff0c;Vue.js 从无到有&#xff0c;从默默无闻到蜚声全球&#xff0c;不仅改变了前端开发的面貌&#xff0c;更成为了无数开发者手中的得力工具。 在…

【常见索引使用】⭐️Mysql中索引的类型以及使用方式和失效场景

目录 一、前言 二、数据准备 三、索引的分类 四、索引示例 示例1、主键索引&#xff08;Primary Key Index&#xff09;与 唯一索引&#xff08;Unique Index&#xff09; 示例2、前缀索引&#xff08;Prefix Index&#xff09; 示例3、联合索引&#xff08;复合索引&am…

鸿蒙 自定义弹窗对CustomDialogController二次封装

前言&#xff1a; 鸿蒙官方提供了自定义customdialog&#xff0c;调用代码很臃肿&#xff0c;必须在当前页面创建customDialogController&#xff0c;否则无法正常弹窗dialog 解决方案&#xff1a;目前就定义了两种类型的dialog 具体代码如下&#xff1a; 1. 用于代理dialog的…

2024内衣洗衣机测评推荐:希亦、小吉、鲸立综合对比哪个牌子好?

对于那些追求品质生活、分类洗涤的用户而言&#xff0c;小型洗衣机可以满足我们对不同类型衣物分开洗涤的需求&#xff0c;例如将内衣、袜子等小件衣物与外套等分开洗涤&#xff0c;以保持衣物的清洁和卫生。并且如果您家中有宝宝&#xff0c;或者您对个人卫生和健康有较高要求…

中国制造赢得世界 外贸独立站wordpress建站案例

孵化器wordpress外贸主题 孵化器、孵化设备wordpress企业主题&#xff0c;适合做孵化器 、孵化设备的企业使用。 https://www.jianzhanpress.com/?p3478 橡胶制品wordpress外贸主题 橡胶制品wordpress外贸主题&#xff0c;橡塑产品对外贸易公司官方网站wordpress模板。 ht…

论文解读:Channel Importance Matters in Few-Shot Image Classification

文章汇总 参考文章ICML2022&#xff5c;Channel Importance Matters in Few-Shot Image Classification - 知乎 一句话总结 Channel bias问题&#xff0c;使模型在迁移到下游小样本分类任务时泛化能力较差&#xff0c;本文在测试阶段仅用一行代码就减弱这个问题的影响。 Ch…

3.7作业

网络聊天室&#xff1a; 程序代码&#xff1a; ser.c #include <myhead.h> //定义消息类型结构体 struct xiaoxi {char type;char name[20];char text[100]; };int main(int argc, const char* argv[]) {// 创建套接字int sfd socket(AF_INET, SOCK_STREAM, 0);if (s…

flutter编译后的windows程序缺少msvcp140.dllvcruntime140.dllvcruntime140_1.dll解决办法

//就是很多博文中提到了三剑客 msvcp140.dll vcruntime140.dll vcruntime140_1.dll 1.没有vs环境的不要把生成的debug下的exe发给别人&#xff0c;会出现莫名其妙的问题。缺少各种DLL文件&#xff0c;我这边收集了上面三个的dll下载链接&#xff1a;flutterdll.rar - 蓝奏云 2…

【动态规划】【数论】【区间合并】3041. 修改数组后最大化数组中的连续元素数目

作者推荐 视频算法专题 本文涉及知识点 动态规划汇总 数论 区间合并 LeetCode3041. 修改数组后最大化数组中的连续元素数目 给你一个下标从 0 开始只包含 正 整数的数组 nums 。 一开始&#xff0c;你可以将数组中 任意数量 元素增加 至多 1 。 修改后&#xff0c;你可以从…

java网络编程 02 socket

01.socket定义 02.TCP编程 import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket;public class clientSocket {public static void main(String[] args) throws IOException {//创建客户端socket&#xff0c;…