【Linux C | 文件I/O】文件的读写 | read、write、lseek 函数

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍 read、write、lseek 函数🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭

本文未经允许,不得转发!!!

目录

  • 🎄一、概述
  • 🎄二、read 函数
  • 🎄三、write 函数
  • 🎄四、lseek 函数
    • ✨4.1 文件偏移量
    • ✨4.2 lseek 函数
  • 🎄五、总结


在这里插入图片描述

🎄一、概述

在Linux系统中,大多数文件I/O只需要用到5个函数:open、read、write、lseek、close,上篇文章介绍了open、creat、close,本文继续介绍剩下的读写操作相关的函数:read、write、lseek。

在这里插入图片描述

🎄二、read 函数

函数原型

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

read 函数可以从打开的文件描述符读取数据。

  • 参数:
    fd,:要操作的文件描述符
    buf:目标缓冲区
    count:期望读取的字节数
  • 返回值:
    成功:返回读取到的字节数。到达文件尾返回0。
    出错:返回 -1。

返回的字节数少于要求读取的字节数的几个情况:

  • 1、读取普通文件时,在读取到要求的字节数之前已经到达文件末尾。例如:距离文件尾端只有30个字节,要求读取100字节,就会返回30,下次再读取返回0.
  • 2、读取终端设备时,通常一次最多读取一行;
  • 3、从网络读取数据时,网络中的缓冲机制可能造成返回值小于要读取的字节数;
  • 4、当从管道或FIFO读时,如若管道包含的字节少于所需的数量,那么read将只返回实际可用的字节数。
  • 5、当从某些面向记录的设备(如磁带)读时,一次最多返回一个记录。
  • 6、当一信号造成中断,而已经读了部分数据量时。读操作从文件的当前偏移量处开始,在成功返回之前,该偏移量将增加实际读到的字节数。

在这里插入图片描述

🎄三、write 函数

函数原型

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

write 函数可以向已打开的文件描述符写入数据。

  • 参数:
    fd:文件描述符
    buf:源数据的缓冲区
    count:期望写入的字节数
  • 返回值:
    成功:返回实际写入字节数
    出错:返回 -1。

其返回值通常与参数count的值相同,否则表示出错。write出错的一个常见原因是:磁盘已写满,或者超过了一个给定进程的文件长度限制。

对于普通文件,写操作从文件的当前偏移量处开始。如果在打开该文件时,指定了O_APPEND选项,则在每次写操作之前,将文件偏移量设置在文件的当前结尾处。在一次成功写之后,该文件偏移量增加实际写的字节数。

在这里插入图片描述

🎄四、lseek 函数

✨4.1 文件偏移量

每个打开的文件都有一个与其相关联的“当前文件偏移量”(current file offset)。它通常是一个非负整数,用以度量从文件开始处计算的字节数。通常,读、写操作都从当前文件偏移量处开始,并使偏移量增加所读写的字节数。按系统默认的情况,当打开一个文件时,除非指定O_APPEND选项,否则该偏移量被设置为0。

✨4.2 lseek 函数

函数原型

#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

write 函数可以修改已打开的文件描述符的文件偏移量。

  • 参数:

    • fd:文件描述符
    • offset:偏移量
    • whence:偏移的起始位置,有三个取值
      SEEK_SET,则将该文件的偏移量设置为距文件开始处offset个字节。
      SEEK_CUR,则将该文件的偏移量设置为其当前值加offset,offset可为正或负。
      SEEK_END,则将该文件的偏移量设置为文件长度加offset,offset可为正或负。
  • 返回值:
    成功:移动后的目标位置与文件开始处的偏移量。
    失败:返回-1。

lseek 函数执行成功后,会返回新的文件偏移量,所以用下面语句来查看文件大小和当前文件偏移量:

size = lseek(fd, 0, SEEK_END);// 文件大小
cur  = lseek(fd, 0, SEEK_CUR);// 查看当前的文件偏移量

这种方法也可用来确定所涉及的文件是否可以设置偏移量。如果文件描述符引用的是一个管道、FIFO或网络套接字,则1seek返回-1,并将errno设置为ESPIPE。

通常,文件的当前偏移量应当是一个非负整数,但是,某些设备也可能允许负的偏移量。但对于普通文件,则其偏移量必须是非负值。因为偏移量可能是负值,所以,在比较lseek的返回值时应当谨慎,不要测试它是否小于0,而要测试它是否等于-1

lseek在超越文件末尾位置写入数据,将文件中形成空洞。文件空洞不占磁盘空间,但被算在文件大小内。

在这里插入图片描述

🎄五、总结

👉介绍Linux C语言编程文件I/O相关的函数:read、write、lseek。
最后看下面例子,帮助理解这几个函数:

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
	char buf[64] = {0};
	int fd = open("./test", O_RDWR | O_CREAT | O_TRUNC, 0775);

	int cur = lseek(fd, 0, SEEK_CUR);
	printf("cur pos=%d\n", cur);

	int writeLen = write(fd, "abcdefg", strlen("abcdefg"));

	cur = lseek(fd, 0, SEEK_CUR);
    printf("cur pos=%d\n", cur);

	int readLen = read(fd, buf, sizeof(buf));// 文件偏移量在末端,返回0,什么也读取不到
	printf("readLen=%d buf=[%s]\n", readLen, buf);

	lseek(fd, -3, SEEK_CUR); // 倒退3个字节,可以读取到 efg
	bzero(buf, sizeof(buf));
	readLen = read(fd, buf, sizeof(buf));
    printf("readLen=%d buf=[%s]\n", readLen, buf);

	lseek(fd, 0, SEEK_SET); // 偏移量移到文件开头, 读取到 abcdefg
	bzero(buf, sizeof(buf));
	readLen = read(fd, buf, sizeof(buf));
	printf("readLen=%d buf=[%s]\n", readLen, buf);

	lseek(fd, 3, SEEK_END); // 在文件末尾之后再偏移 3 个字节,会形成空洞
	writeLen = write(fd, "abcdefg", strlen("abcdefg")); // 写完后,会有17个字节,7+3+7
	lseek(fd, 0, SEEK_SET); // 偏移量移到文件开头, 读取到 abcdefg   abcdefg
	bzero(buf, sizeof(buf));
	readLen = read(fd, buf, sizeof(buf));
	int size =  lseek(fd, 0, SEEK_END); // 偏移到文件末端,查看文件大小
    printf("readLen=%d buf=[%s] size=%d\n", readLen, buf, size);// 这里的buf会打印不全,因为有3个空洞字节,读出来是0
	int i=0;
	for(i=0; i<size; i++)
	{
		printf("%d=%d\n",i, buf[i]);
	}

	close(fd);
	return 0;
}

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

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

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

相关文章

一个简单的 HTTP 请求和响应服务——httpbin

拉取镜像 docker pull kennethreitz/httpbin:latest 查看本地是否存在存在镜像 docker images | grep kennethreitz/httpbin:latest 创建 deployment&#xff0c;指定镜像 apiVersion: apps/v1 kind: Deployment metadata:labels:app: httpbinname: mm-httpbinnamespace: mm-…

[管理者与领导者-129]:很多人对高情商的误解,工程师要扩展自己的情商吗?工程师如何扩展自己的情商?

目录 前言&#xff1a; 一、什么是高情商&#xff1f; 1.1 什么是高情商 1.2 情商的五大能力 1.3 高情商的层次 1.4 对高情商的误解? 二、工程师需要发展自己的高情商吗&#xff1f; 三、工程师如何扩展自己的情商&#xff1f; 四、什么样的“高情商”的管理者令人讨…

攻防世界——Hello, CTF

运行可以发现这是输入型的flag &#xff08;re题目分为两类&#xff0c;一种你直接输入flag&#xff0c;还有一种就是你完成某个操作后&#xff0c;给你flag&#xff09; 可以发现关键字符串就是wrong 和 input 32位 IDA打开 进入直接进入字符串界面&#xff0c;发现关键字符…

使用Swift Package Manager (SPM)实现xcframework分发

Swift Package Manager (SPM) 是苹果官方提供的用于管理 Swift 项目的依赖关系和构建过程的工具。它是一个集成在 Swift 编程语言中的包管理器&#xff0c;用于解决在开发过程中管理和构建包依赖项的需求。 1、上传xcframework.zip到服务端 压缩xcframeworks成一个zip包&…

SqlServer数据取头取尾

SqlServer数据取头取尾 案列一&#xff1a; --表有以下字段和数据 DROP TABLE #temptable CREATE TABLE #temptable ( [SN] nvarchar(255), [STATUSCODE] int, [NAME] nvarchar(255), [STATUSDESC] nvarchar(255), [REASON] nvarchar(255), [RUNTIME] datetime, [END_TIME] d…

js 图片 手动上传,并回显

效果展示&#xff1a; 代码&#xff1a; <label for"avatarUpload"><div><img v-if"avatatImageUrl" :src"avatatImageUrl" class"avatar"><img v-else src"../../assets/images/account/avatar-upload.png…

60、UART任意时间缓冲打印信息--解决写代码调试时中断中打印信息问题

/********************************************************************** *file:UART任意时间缓冲打印信息–解决写代码调试时中断中打印信息问题 *author:残梦 *versions:V1.0 *date:2023.12.23 note: 方案&#xff1a;创建一个缓冲区&#xff0c;任意时间添加数据至缓冲区…

C++设计模式 #3策略模式(Strategy Method)

动机 在软件构建过程中&#xff0c;某些对象使用的的算法可能多种多样&#xff0c;经常改变。如果将这些算法都写在类中&#xff0c;会使得类变得异常复杂&#xff1b;而且有时候支持不频繁使用的算法也是性能负担。 如何在运行时根据需求透明地更改对象的算法&#xff1f;将…

重生奇迹mu翅膀合成

在重生奇迹mu中&#xff0c;合成翅膀需要准备好翅膀碎片、宝石、羽毛、强化精华等材料&#xff0c;而其中不同翅膀合成要求的材料和数量略有不同。以下是一般合成翅膀的步骤&#xff1a; 1.首先&#xff0c;需要在背包中准备好所有的合成材料。如果缺少任何一种材料&#xff0…

Postman —— HTTP请求基础组成部分

一般来说&#xff0c;所有的HTTP Request都有最基础的4个部分组成&#xff1a;URL、 Method、 Headers和body。 &#xff08;1&#xff09;Method 要选择Request的Method是很简单的&#xff0c;Postman支持所有的请求方式。 &#xff08;2&#xff09;URL 要组装一条Request&…

【C++进阶02】多态

一、多态的概念及定义 1.1 多态的概念 多态简单来说就是多种形态 同一个行为&#xff0c;不同对象去完成时 会产生出不同的状态 多态分为静态多态和动态多态 静态多态指的是编译时 在程序编译期间确定了程序的行为 比如&#xff1a;函数重载 动态多态指的是运行时 在程序运行…

Java整合APNS推送消息-IOS-APP(基于.p12推送证书)

推送整体流程 1.在开发者中心申请对应的证书&#xff08;我用的是.p12文件&#xff09; 2.苹果手机用户注册到APNS&#xff0c;APNS将注册的token返回给APP&#xff08;服务端接收使用&#xff09;。 3.后台服务连接APNS&#xff0c;获取连接对象 4.后台服务构建消息载体 5.后台…

Windows漏洞利用开发——利用SEH绕过GS保护

实验6 Windows漏洞利用开发 6.1实验名称 Windows漏洞利用开发 6.2实验目的 学习windows漏洞利用开发&#xff0c;使用kali linux相关工具对windows内目标程序进行漏洞利用 6.3实验步骤及内容 第二阶段&#xff1a;利用SEH绕过GS保护 了解GS编译选项&#xff0c;SHE异常处…

最小二乘法简介

最小二乘法简介 1、背景描述2、最小二乘法2.1、最小二乘准则2.2、最小二乘法 3、最小二乘法与线性回归3.1、最小二乘法与线性回归3.2、最小二乘法与最大似然估计 4、正态分布&#xff08;高斯分布&#xff09; 1、背景描述 在工程应用中&#xff0c;我们通常会用一组观测数据去…

数据大模型与低代码开发:赋能技术创新的黄金组合

在当今技术领域&#xff0c;数据大模型和低代码开发已经成为两个重要的趋势。数据大模型借助庞大的数据集和强大的计算能力&#xff0c;助力我们从海量数据中挖掘出有价值的洞见和预测能力。与此同时&#xff0c;低代码开发通过简化开发流程和降低编码需求&#xff0c;使得更多…

Flink实时电商数仓(五)

FlinkSQL的join Regular join普通join&#xff0c;两条流的数据都时存放在内存的状态中&#xff0c;如果两条流数据都很大&#xff0c;对内存压力很大。Interval Join: 适合两条流到达时间有先后关系的&#xff1b;一条流的存活时间短&#xff0c;一条流的存活时间长。Lookup …

【机器学习】贝叶斯决策论

参考课程视频&#xff1a;https://www.icourse163.org/course/NEU-1462101162?tid1471214452 1 概述 1.1 相关概念与变量描述 1.2 贝叶斯定理 2 分类准则 2.1 最大后验概率分类准则 2.2 最小错误概率分类准则 ) 2.3 最小风险分类准则 2.4 栗子 —— 根据身高预测性别

基于AWD攻防对Web漏洞的研究

写在前面 Copyright © [2023] [Myon⁶]. All rights reserved. 基于awd攻防环境和xshell远程连接&#xff0c;配合kali linux渗透系统、蚁剑、D盾、河马、Seay代码审计系统等&#xff0c;演示现实中网站可能存在的漏洞&#xff0c;对网站进行漏洞扫描&#xff0c;渗透测…

网络爬虫之Ajax动态数据采集

动态数据采集 规则 有时候我们在用 requests 抓取页面的时候&#xff0c;得到的结果可能和在浏览器中看到的不一样&#xff0c;在浏览器中可以看到正常显示的页面教据&#xff0c;但是使用 requests 得到的结果并没有&#xff0c;这是因为requests 获取的都是原始的 HTML 文档…

nodejs+vue+ElementUi家政服务系统c90g5

项目中登录模块用到token家政服务平台有管理员&#xff0c;雇主&#xff0c;雇员三个角色。管理员功能有个人中心&#xff0c;雇主管理&#xff0c;雇员管理&#xff0c;资料认证管理&#xff0c;项目类型管理&#xff0c;服务项目管理&#xff0c;需求信息管理&#xff0c;服务…