Linux文件编程——read函数与lseek函数
一、read函数
在 Linux 文件编程中,read
函数是一个系统调用,用于从文件描述符(File Descriptor)指向的文件或设备中读取数据到缓冲区。它是 Unix/Linux 系统编程中实现底层 I/O 操作的核心函数之一。以下是 read
函数的详细使用方法和注意事项。
1. 函数原型
#include <unistd.h>ssize_t read(int fd, void *buf, size_t count);
- 参数:
fd
:文件描述符(通过open
或creat
等函数获得)。buf
:指向存储读取数据的缓冲区的指针。count
:要读取的最大字节数。
- 返回值:
- 成功时返回实际读取的字节数(可能小于
count
,例如到达文件末尾时返回0
)。 - 失败时返回
-1
,并设置errno
表示错误原因。
- 成功时返回实际读取的字节数(可能小于
2. 使用方法
基本示例
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>int main() {int fd;char buf[256];ssize_t bytes_read;// 打开文件(只读模式)fd = open("example.txt", O_RDONLY);if (fd == -1) {perror("open failed");return 1;}// 读取数据bytes_read = read(fd, buf, sizeof(buf) - 1); // 保留一个字节给 '\0'if (bytes_read == -1) {perror("read failed");close(fd);return 1;}// 添加字符串终止符并打印buf[bytes_read] = '\0'; // 确保是字符串printf("Read %zd bytes: %s\n", bytes_read, buf);// 关闭文件close(fd);return 0;
}
关键步骤
- 打开文件:
- 使用
open
函数获取文件描述符,指定读取模式(如O_RDONLY
)。
- 使用
- 读取数据:
- 调用
read(fd, buf, count)
,将数据从文件读取到buf
中。 - 检查返回值,确保读取成功。
- 调用
- 处理数据:
- 如果读取的是文本数据,通常需要手动添加字符串终止符
\0
。
- 如果读取的是文本数据,通常需要手动添加字符串终止符
- 关闭文件:
- 使用
close(fd)
释放文件描述符。
- 使用
3. 注意事项
(1) 返回值处理
- 正常情况:
- 返回实际读取的字节数(可能小于
count
,例如文件末尾或缓冲区不足)。 - 返回
0
表示已到达文件末尾(EOF)。
- 返回实际读取的字节数(可能小于
- 错误情况:
- 返回
-1
,需检查errno
(如EBADF
、EINTR
、EIO
等)。
- 返回
- 示例代码(循环读取):
ssize_t total_read = 0;
while (total_read < count) {ssize_t bytes_read = read(fd, buf + total_read, count - total_read);if (bytes_read == -1) {if (errno == EINTR) continue; // 被信号中断,重试perror("read failed");break;} else if (bytes_read == 0) {break; // EOF}total_read += bytes_read;
}
(2) 错误处理
- 常见错误包括:
EBADF
:无效的文件描述符。EINTR
:被信号中断(需重试)。EIO
:底层 I/O 错误。EAGAIN
/EWOULDBLOCK
:非阻塞模式下无数据可读(需结合select
/poll
使用)。
- 使用
perror
或strerror(errno)
打印错误信息。
(3) 缓冲与非阻塞 I/O
read
是无缓冲的(直接调用系统调用),但文件可能因缓冲设置(如O_NONBLOCK
)或设备特性而阻塞。- 对于非阻塞文件描述符(如套接字),
read
可能返回EAGAIN
或EWOULDBLOCK
,需结合select
/poll
使用。
(4) 性能优化
- 批量读取(减少系统调用次数)。
- 使用
mmap
映射文件到内存(适合大文件随机访问)。 - 对于大文件,考虑
pread
进行分散/聚集读取(Scatter-Gather I/O)。
(5) 安全性
- 确保缓冲区
buf
的大小足够,避免缓冲区溢出。 - 验证文件描述符
fd
的合法性(如通过fstat
检查)。 - 避免读取未初始化的数据或越界访问。
(6) 信号中断
- 如果
read
被信号中断(EINTR
),通常需要重新尝试读取。
(7) 二进制 vs 文本数据
read
是字节级操作,不关心数据格式(文本或二进制)。- 读取文本时需手动处理换行符或编码问题。
4. 替代函数
pread
:在指定偏移量处读取(无需lseek
)。readv
:聚集读取(将数据分散到多个缓冲区)。recv
:网络编程中用于套接字的读取(支持标志位)。
5. 常见问题
(1) 为什么 read
返回的字节数小于 count
?
- 文件末尾(EOF)。
- 缓冲区不足。
- 信号中断(
EINTR
)。 - 非阻塞 I/O 且无数据可读(
EAGAIN
/EWOULDBLOCK
)。
(2) 如何确保读取完整数据?
- 循环读取,直到满足条件(如读取到特定分隔符或固定长度)。
- 示例(读取固定长度数据):
#define FIXED_SIZE 1024
char buf[FIXED_SIZE];
ssize_t total = 0;
while (total < FIXED_SIZE) {ssize_t ret = read(fd, buf + total, FIXED_SIZE - total);if (ret <= 0) break; // 错误或 EOFtotal += ret;
}
(3) 如何处理大文件?
- 使用
mmap
映射文件到内存,避免频繁read
。 - 分块读取并处理。
6. 总结
read
是 Linux 文件编程的基础函数,使用时需注意:
- 正确处理返回值:区分 EOF、错误和部分读取。
- 错误处理:检查
errno
并处理信号中断。 - 性能优化:批量读取、避免频繁系统调用。
- 安全性:防止缓冲区溢出和非法访问。
- 非阻塞 I/O:结合
select
/poll
使用。
通过合理使用 read
,可以高效、可靠地完成文件 I/O 操作。
二、lseek
函数的使用方法
1.函数原型
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
- 参数:
fd
:文件描述符。offset
:偏移量(字节数),可正可负。whence
:基准点,取值如下:SEEK_SET
:从文件开头偏移。SEEK_CUR
:从当前位置偏移。SEEK_END
:从文件末尾偏移。
- 返回值:成功时返回新的文件偏移量,失败时返回
-1
并设置errno
。
2.典型用途
随机访问文件:通过定位到文件的任意位置进行读写。例如,读取文件第1024字节处的512字节数据:
int fd = open("data.dat", O_RDONLY);
lseek(fd, 1024, SEEK_SET); // 定位到文件开头后1024字节处
char buf[512];
read(fd, buf, sizeof(buf));
close(fd);
获取文件大小:通过定位到文件末尾,再获取当前偏移量:
int fd = open("file.txt", O_RDONLY);
off_t size = lseek(fd, 0, SEEK_END); // 偏移量为文件大小
printf("File size: %lld bytes\n", (long long)size);
close(fd);
创建空洞文件:通过将偏移量移动到超过当前文件大小的位置,再写入数据,中间的区域会被视为空洞(不占用磁盘空间):
int fd = open("large_file.dat", O_CREAT | O_WRONLY, 0644);
lseek(fd, 1024 * 1024 * 1024 - 1, SEEK_SET); // 定位到1GB偏移处(最后一个字节)
write(fd, "", 1); // 写入一个字节,文件大小变为1GB
close(fd);
三、lseek
函数的注意事项
- 返回值检查
- 成功时返回新的文件偏移量,失败时返回
-1
,不能用<0
判断,因为偏移量可能是负的(如SEEK_CUR
或SEEK_END
为基准且offset
为负时)。 - 必须检查返回值以确保操作成功。
- 成功时返回新的文件偏移量,失败时返回
- 文件类型限制
lseek
仅适用于支持随机访问的文件(如普通文件),对管道、套接字等流式文件无效。例如,在管道或设备文件上调用lseek
会失败,返回-1
且errno=ESPIPE
。
- 偏移量溢出风险
- 在32位系统中,
off_t
为4字节,偏移量超过2GB可能导致溢出。64位系统中,off_t
为8字节,可处理更大的文件。
- 在32位系统中,
- 并发与原子性
lseek
是原子操作,多线程环境下无需额外同步,但读写操作仍需考虑线程安全。
- 文件打开模式的影响
- 如果文件以追加模式(
O_APPEND
)打开,lseek
设置的偏移量对write
操作无效,write
仍会追加到文件末尾。
- 如果文件以追加模式(
四、lseek
与read
函数的关系
- 协同工作
lseek
用于调整文件的读写位置,read
用于从当前位置读取数据。例如:
int fd = open("file.txt", O_RDONLY);
lseek(fd, 100, SEEK_SET); // 定位到第100字节
char buf[10];
read(fd, buf, sizeof(buf)); // 从第100字节开始读取10字节
close(fd);
- 文件偏移量的更新
read
函数会更新文件的当前偏移量,而lseek
可以显式地修改偏移量。两者共同决定了下一次读写操作的位置。
- 性能优化
在需要随机访问文件时,lseek
可以避免不必要的顺序读取,提高效率。例如,在数据库文件中,通过lseek
直接定位到指定记录的起始位置进行读写操作。
- 错误处理的关联性
如果lseek
调用失败,后续的read
操作可能会读取到错误的数据或返回错误。因此,必须在使用lseek
后检查其返回值。
相关文章:
Linux文件编程——read函数与lseek函数
一、read函数 在 Linux 文件编程中,read 函数是一个系统调用,用于从文件描述符(File Descriptor)指向的文件或设备中读取数据到缓冲区。它是 Unix/Linux 系统编程中实现底层 I/O 操作的核心函数之一。以下是 read 函数的详细使用…...
[思维模式-38]:看透事物的关系:什么是事物的关系?事物之间的关系的种类?什么是因果关系?如何通过数学的方式表达因果关系?
一、什么是事物的关系? 事物的关系是指不同事物之间存在的各种联系和相互作用,它反映了事物之间的相互依存、相互影响、相互制约等特性。以下从不同维度为你详细阐述: 1、关系的类型 因果关系 定义:一个事件(原因&a…...
【2025.5.12】视觉语言模型 (更好、更快、更强)
【2025.5.12】Vision Language Models (Better, Faster, Stronger): https://huggingface.co/blog/vlms-2025 【2024.4.11】Vision Language Models Explained【先了解视觉语言模型是什么】: https://huggingface.co/blog/vlms nanoVLM: https://github.…...
Spring的bean的生命周期?
Spring中bean的生命周期包括以下步骤: 通过BeanDefinition获取bean的定义信息。 调用构造函数实例化bean。 进行bean的依赖注入,例如通过setter方法或Autowired注解。 处理实现了Aware接口的bean。 执行BeanPostProcessor的前置处理器。 调用初始化…...

Qwen集成clickhouse实现RAG
一、RAG概要 RAG(Retrieval-Augmented Generation,检索增强生成) 是一种结合了信息检索技术与语言生成模型的人工智能技术。旨在通过检索相关文档来增强大模型的生成能力,从而提高预测的质量和准确性。RAG模型在生成文本或回答…...

Excel分组计算求和的两种实现方案
文章目录 背景样例数据方案一、函数求和实现步骤缺点 方案二、数据透视表实现步骤优点 背景 在Excel文档中,经常会进行数据的求和计算,可使用不同的方式实现,记录下来,方便备查。 样例数据 已有商品销量信息,包含销…...
深入理解卷积神经网络:从基础原理到实战应用
在人工智能领域,卷积神经网络(Convolutional Neural Network,简称 CNN)凭借其强大的图像识别、处理能力,成为深度学习中不可或缺的技术。无论是自动驾驶汽车识别道路标志,还是医学影像分析辅助疾病诊断&…...

LLM定制新路径:微调与上下文学习的博弈与融合
在当今人工智能的浪潮中,大型语言模型(LLMs)已成为推动行业进步的关键力量。无论是自然语言处理、文本生成还是多模态应用,LLMs都在展现着它们的强大能力。然而,当我们将这些强大的模型应用于特定的下游任务时…...
【江苏省】《信息技术应用创新软件适配改造成本评估规范》(DB32/T 4935-2024)-标准解读系列
在信息技术应用创新产业蓬勃发展的当下,软件适配改造成本评估成为项目实施的关键环节。《DB32/T 4935-2024 信息技术应用创新软件适配改造成本评估规范》应运而生,为成本评估提供了专业依据。同时,《省级政务信息化项目建设方案编制规范&…...
JDK 命令行工具大全与学习方法总结 —— 从帮助文档到高效实践
JDK 命令行工具大全与学习方法总结 —— 从帮助文档到高效实践 Java开发与运维过程中,JDK自带的命令行工具是定位问题、性能调优、编译调试的基石。本文全面梳理JDK常用命令工具、帮助文档的获取方式,并总结类似Linux命令行的学习方法,助你系…...

嵌入式中深入理解C语言中的指针:类型、区别及应用
在嵌入式开发中,C语言是一种基础且极为重要的编程语言,其中指针作为一个非常强大且灵活的工具,广泛应用于内存管理、动态数据结构的实现以及函数参数的传递等方面。然而,尽管指针的使用极为常见,很多开发者在掌握其基本使用后,往往对指针的深入理解还不够。本文将深入分析…...

香港维尔利健康科技集团成都区域运营中心投入使用,西南市场战略全面提速
近日,香港维尔利健康科技集团正式宣布,其位于四川成都的西南区域运营中心已全面建成并投入使用。该中心将集设备调配、技术支持、客户服务、运营管理及数字健康平台维护于一体,成为集团在中国内地智慧医疗战略版图中的关键枢纽,对…...

STM32CubeMX HAL库 串口的使用
1.配置 2.开启中断后,生成代码 3.串口的接收 1).开启空闲中断接收 __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE); // 关键步骤:启用空闲中断 2). 启动接收 调用 HAL_UARTEx_ReceiveToIdle_IT 启动异步接收,可以使用…...
二手车估值接口介绍
二手车估值接口是基于大数据和机器学习技术开发的工具,旨在为二手车交易、金融评估等场景提供快速、精准的车辆价值评估服务。以下从核心功能、技术原理、接口特点及应用场景等方面进行综合介绍: 一、核心功能 多维度数据采集与分析 接口整合了车辆基础…...

flutter 视频通话flutter_webrtc
flutter 比较热门的库 flutter_webrtc | Flutter package agora_rtc_engine | Flutter package 我使用的是flutter_webrtc 下面是官方推荐的demo库 GitHub - flutter-webrtc/flutter-webrtc-demo: Demo for flutter-webrtc 其中 https://demo.cloudwebrtc.com:8086/ 已经停…...

Babylon.js学习之路《四、Babylon.js 中的相机(Camera)与视角控制》
文章目录 1. 引言:为什么相机是 3D 场景的“眼睛”?1.1 相机的核心作用1.2 常见相机类型概览 2. 相机基础参数解析2.1 通用属性2.2 相机坐标系 3. 详解常用相机类型3.1 自由相机(FreeCamera)3.2 弧形旋转相机(ArcRotat…...

【Redis实战篇】秒杀优化
1. 秒杀优化-异步秒杀思路 我们来回顾一下下单流程 当用户发起请求,此时会请求nginx,nginx会访问到tomcat,而tomcat中的程序,会进行串行操作,分成如下几个步骤 1、查询优惠卷 2、判断秒杀库存是否足够 3、查询订单…...
RHCE认证通过率
红帽RHCE考试总体通过率38%(2023年数据),细分数据显示自学者通过率18%,参加官方培训者47%,企业团体考生53%。通过率差异由备考资源和考试策略决定。 RHCE考试重点考Ansible自动化运维,需在3.5小时内完成12…...
外贸礼品禁忌
一、亚洲 1.印度 牛是神圣动物,别送牛皮制品。另外,左手不洁,送礼得用右手或双手。 2.日本 “梳” 和 “苦” 谐音,不送梳子。日本男性不咋佩戴首饰,除结婚戒指。礼物得装盒、纸包、绳饰,白色包装得有…...

Trae IDE:AI深度集成的智能开发环境
(以高效人机协作重塑编程体验) 概述 Trae IDE(发音 /treɪ/)是一款深度集成AI能力的现代化开发工具,结合传统IDE的完备功能与前沿AI技术,提供智能问答、代码自动补全、跨文件编程及AI Agent驱动的自动化开…...

【大模型】AI智能体Coze 知识库从使用到实战详解
目录 一、前言 二、知识库介绍 2.1 coze 知识库功能介绍 2.2 coze 知识库应用场景 2.3 coze 知识库类型 2.4 coze 知识库权限说明 2.5 coze 知识库与记忆对比 2.6 知识库的使用流程 三、知识库创建与使用 3.1 创建知识库入口 3.2 创建文本知识库 3.2.1 上传文件 3.…...

【springcloud学习(dalston.sr1)】服务消费者通过restTemplate来访问服务提供者(含源代码)(五)
该系列项目整体介绍及源代码请参照前面写的一篇文章【springcloud学习(dalston.sr1)】项目整体介绍(含源代码)(一) 一般情况下,我们远程调用服务,可以用restTemplate来进行http请求的访问。接…...

打破边界,智评未来:AI如何重塑学科交叉融合的评价体系?
目录: 引言:当“学科孤岛”遇上“创新浪潮”透视现状:学科交叉融合的“热望”与“冰壁”他山之石:国际交叉融合模式与评价的“镜与灯”AI赋能:重构学科交叉评价的内涵、要素与方法论 4.1. 基本内涵:从“知识叠加”到“价值涌现”4.2. 评价要素:超越“单点指标”的“网络…...

ULVAC C30HMVRT系列冷冻泵和超捕集器压缩机组 安装、操作、维护和故障排除说明 含电路图
ULVAC C30HMVRT系列冷冻泵和超捕集器压缩机组 安装、操作、维护和故障排除说明 含电路图...

ORACLE查看归档是否打开
一、使用V$DATABASE视图 SELECT log_mode FROM v$database; 结果说明: ARCHIVELOG - 数据库处于归档模式 NOARCHIVELOG - 数据库处于非归档模式 二、 使用v$instance视图 SELECT archiver FROM v$instance; 结果说明: STARTED - 归档进程已启动(归档模…...

鸿蒙5.0项目开发——鸿蒙天气项目的实现(介绍)
【高心星出品】 文章目录 项目简介:项目运行效果图:主要功能:使用的技能点:开发环境: 项目简介: 这是一个基于鸿蒙系统(HarmonyOS)开发的天气应用,采用 ArkTS 语言开发&…...

3Dblox
TSMC 3Dblox Introduction 3Dblox是TSMC定义的一门语言,目标是将物理封装系统分解为模块化的组件,然后进行集成 RDL : 代表interposer的部分 Die的实例化信息 堆叠信息 连接信息 thickness:Die与Die连接Bump的高度 RedHawk-SC-Electrothermal…...

Python+大模型 day01
Python基础 计算机系统组成 基础语法 如:student_num 4.标识符要做到见名知意,增强代码的可读性 关键字 系统或者Python定义的,有特殊功能的字符组合 在学习过程中,文件名没有遵循标识符命名规则,是为了按序号编写文件方便查找复习 但是,在开发中,所有的Python文件名称必须…...

磁光克尔效应在量子计算中的应用
一、量子自旋态光学操控 1、拓扑量子态探测 磁光克尔效应通过检测拓扑磁结构(如磁斯格明子)的磁光响应,实现对量子材料中非平庸拓扑自旋序的非侵入式表征。例如,二维量子磁体中的“拓扑克尔效应”可通过偏振光旋转角变化揭示…...
【FileZilla】sftp协议的数据传输上传和下载
基于前面两篇及B站上大牛小方的解析视频: 【1】【Filezilla】 dispatch函数重载的例子-CSDN博客 【2】【C】【FileZilla】事件调用机制代码解析-CSDN博客 当线程entry()调用process_event()时,通过语句 (*std::get<0>(ev0))(*std::get<1>(…...