【UNIX环境高级编程】【笔记一:不带缓冲的I/O read和write机制】

《UNIX环境高级编程》笔记:第3章 文件I/O “本章说明了UNIX系统提供的基本I/O函数。因为read和write都在内核执行,所以称这些函数为不带缓冲的I/O函数。在只使用read和write情况下,我们观察了不同的I/O长度对读文件所需时间的影响。我们也观察了许多将已写入的数据冲洗到磁盘上的方法,以及它们对应用程序性能的影响。 在说明多个进程对同一文件进行追加写操作以及多个进程创建同一文件时,本章介绍了原子操作。也介绍了内核用来共享打开文件信息的数据结构。” 阅读详情


前言

在linux系统编程中,我们经常会使用到输入和输出函数,其中涉及带缓冲区的输入输出和不带缓冲区的输出输出函数,他们的作用各不相同,本文主要讨论不带缓冲区的输入输出函数,并介绍他们在读取文件的过程中,文件的偏移量是如何进行变化的。


一、不带缓冲区的输入输出函数是指什么?

不带缓冲区的输入函数是指read函数,不带缓冲区的输出函数是指write函数,当文件被open函数打开时,我们如果需要从该文件中读取数据则可以使用read函数,如果需要写入数据到该文件中,我们可以使用write函数,具体的函数原型如下。

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);
//注:成功返回值为读到的字节数,如果到了文件末尾则返回0;出错返回-1

ssize_t write(int fd, const void *buf, size_t count);
//注:成功返回值为已写的字节数;出错返回-1

ssize_t为带符号的整形数据。

二、read函数的读取机制是什么?

当某个文件被open打开时,我们使用read函数从该文件中读取一段小于文件长度的数据时,read函数将从当前文件的偏移量处开始进行读取数据,在read函数成功返回前,该文件的偏移量被操作,偏移量会增加实际已被读取到的字节数,随后read返回实际读取到的字节数。

三、write函数的写入机制是什么?

同理,当某个文件被open打开时,我们使用write函数将一段数据从当前文件偏移量开始写入,随后write返回实际写入的字节数;当使用open函数指定从文件尾开始追加时,则在每次写入之前,先操作文件的偏移量至文件末尾,再从当前文件偏移量出写入该数据,随后write返回实际写入的字节数。

四、如何连续使用read函数?

当使用read函数当作通信类读取接口时,假设本地设备为主机,远程设备为从机,此时从机连续不间断地向主机发送数据,作为主机,需源源不断地被动从从机读取数据,

while(有数据到来时)
{
	实际的字节数= read(设备的文件描述符,读数据缓存区+累计字节数,预计单次能读取的字节数);
	if(实际的字节数 == 0||实际的字节数 == -1)
	break;
	累加的字节数+=实际的字节数;
}

当有数据到来时,初始的累计字节数和实际的字节数被清零处理,第一次调用read函数时,将读取到的实际数据存储到缓存区中,由于初始时累计字节数为0,所以读到的数据从存储区初始位置开始填充;当一段数据被分成多次发送时,第二次调用read函数则会将读到的实际数据存储到存储区,且存储的位置为存储区向后偏移累加的字节数的位置开始存储数据,以此完成第二段数据的拼接过程,之后的第三段、第四段数据因此能够顺利的全部存储在指定的存储区中;当读取到的数据返回值为0时,表明数据已被读取完毕,此次结束并退出循环操作。
这样就可以完整的获取一段分散发送的数据了。

五、如何连续使用write函数?

当使用write函数写入通信类接口时,假设本地设备为主机,远程设备为从机,此时主机主动向从机发送数据:

while(剩余缓存区的长度大于0)
{
	if(剩余缓存区的长度小于预计单次能发送的字节数)
	{
		实际写入的字节数= write(设备的文件描述符,待发送缓冲区+累计字节数,剩余缓存区的长度);
	}
	else
	{
		实际写入的字节数= write(设备的文件描述符,待发送缓冲区+累计字节数,预计单次能发送的字节数);
	}
	if(实际写入的字节数 == -1)
	break;
	累加的字节数+=实际写入的字节数;
	剩余缓存区的长度 = 缓存区的长度 - 累加的字节数;
}

当缓存区的长度大于0时,初始的累计字节数和实际写入的字节数被清零处理,剩余缓存区长度为缓存区的实际数据长度,假设剩余缓存区长度大于预计单次能发送的字节数,第一次调用write函数时,将缓存区预计单次能发送的字节数发送出去,由于初始时累计字节数为0,所以发送的数据从存储区初始位置开始发送;当一段数据被分成多次发送时,且此时剩余缓存区的长度小于单次预计能发送的字节数。则第二次调用write函数会发送剩余缓存区的长度,当剩余缓存区的长度为0时,表明数据已被发送完毕,此次结束并退出循环操作。
这样就可以完整的发送一段分散发送的数据了。

总结

例如:以上就是今天要讲的内容,本文仅仅简单介绍了read和write函数的一些使用机制,涉及偏移量移动的一些细节知识以及连续使用的一些知识对其作了一番简单介绍和引用。

SpringBoot3项目实战:5分钟搞定Knife4j接口文档配置(含中文版设置) 本文详细介绍了在SpringBoot3项目中快速整合Knife4j接口文档工具的实战教程。内容涵盖核心依赖选择、基础配置、中文界面设置、API信息深度定制以及生产环境安全策略,帮助开发者高效构建专业、可交互的API文档门户,提升团队协作效率。 阅读详情

相关推荐

halcon 深度学习标注_Halcon deep learning之目标检测笔记(一)

设置输入输出的路径输入路径有两个,一个是图像路径HalconImageDir,一个是Json文件路径PillBagJsonFile。这两个参数用于后续在图像路径中读取coco文件。输出路径首先定义一个新的文件夹路径,用于存放样本和模型文件等数据。设置基于深度学习的目标检测模型的路径,该模型文件以.hdl结尾。设置样本数据文件夹ExampleDataDir:'detect_pills_data'数据...

weixin_27885313的博客 2699

Linux中不带缓冲区的write和带缓冲区的printf/fputs区别,以及Linux中的进程缓冲区拷贝

在Linux中,write是不带缓冲区的函数,也就是其写完以后不会在缓冲区中存储,直接写出。 考虑以下代码 1、使用fputs # include <unistd.h> # include <stdio.h> # include <stdlib.h> # include <errno.h> int main(void) { FILE *stream; if ((stream = fopen ( "./log.txt" , "a" ))

weixin_43353102的博客 1601

[TC3XX]AURIX TC3XX系列之启动流程

本文介绍了微控制器(MCU)启动过程中固件(Firmware)和启动软件(SSW)的工作原理。MCU上电复位后,硬件完成初始化,BootROM中的固件开始执行,进行参数加载、模式选择等操作。SSW作为第一个执行的软件,负责时钟配置、安全检查、多核管理及启动模式选择,最终跳转至用户代码。启动模式包括内部Flash启动、Bootloader模式(通过ASC或CAN接口)和备用启动模式(ABM),具体由复位类型、引脚配置和UCB设置决定。文章特别指出英飞凌TC3xx系列芯片中固件不可修改,只能通过配置参数定制启动

redparrot2008的博客 1420

C/C++ 的全缓冲、行缓冲和无缓冲

1.简介 基于流的操作最终会调用read或者write函数进行I/O操作。为了使程序的运行效率最高,流对象通常会提供缓冲区,以减少调用系统I/O库函数的次数。 在Linux中,缓冲方式存在三种,分别是: (1)全缓冲。输入或输出缓冲区被填满,会进行实际I/O操作。其他情况,如强制刷新、进程结束也会进行实际I/O操作。 对于读操作来说,当读入内容的字节数等于缓冲区大小或者文件已经到达结尾,或

Doublelv 的博客专栏。 8605

别再乱点U盘里的.exe了!手把手教你清除‘Usb Disk.exe’病毒并恢复隐藏文件

本文详细介绍了如何识别和清除U盘病毒(如Usb Disk.exe),并提供从终止病毒进程到恢复隐藏文件的完整步骤。通过禁用自动播放、清理注册表和使用命令行工具,帮助用户彻底清除病毒并预防未来感染,确保数据安全。

weixin_42530732的博客 591

手把手教你用FreeModbus RTU协议栈实现STM32与PLC通信(附Keil工程)

本文详细介绍了如何使用FreeModbus RTU协议栈在STM32上实现与PLC的工业通信。从环境搭建、工程配置到关键移植接口实现,提供了Keil工程模板和调试技巧,帮助开发者快速掌握Modbus RTU通信技术,适用于工业自动化领域的设备间通信需求。

weixin_42549037的博客 418

UNIX环境编程:文件I/O

★内容概述: 本章主要讲了文件I/O,即不带缓冲的I/O,然后介绍了不带缓冲I/O函数随后介绍了文件共享实现方式,主要是使用3种数据结构实现(进程表项,文件表项,v-node和i-node)。然后从文件共享提出了一个问题,就是多个进程同时操作文件可能产生的数据一致性问题,由此又介绍了两个原子操作(pread和pwrite)。最后介绍了常用的I/O控制函数。

_ 1174

QGIS基于快鸟(QuickBird)影像统计小麦种植面积

​01数据情况 本次选用某地4月份快鸟(QuickBird)影像为例,使用QGIS演示提取小麦播种情况,并按照200米*200米分区计算种植面积的过程。 注:本文对应的操作视频作为今天第二篇推送同时发布,习惯看视频的朋友可以点击观看。 附数据压缩包: 链接:https://pan.baidu.com/s/1JVUS8uAOR61RxC1n9Or9_w 提取码:qgis 含快鸟影像QB_subset.tif和200*200米分区矢量图层200Mgrid.shp。 ...

QGISClass的博客 1979

《UNIX环境高级编程》读书笔记04: 文件I/O

文件元数据包括文件所有者、文件大小、访问权限、修改时间等信息。调用。

2159

【YOLO26创新改进】TGRS 2026 | Transformer变体改进篇 | 使用CGTA曲率引导令牌注意力,改善结构与纹理的整体协调,适合遥感小目标检测、旋转目标检测、实例分割任务

本文在YOLO26目标检测模型中引入CGTA曲率引导令牌注意力模块,依据曲率显著性与特征可靠性,从高分辨率特征图中筛选少量关键令牌,再让全部位置与这些代表性特征进行全局交互,从而以较低计算和显存开销建立远距离目标、背景及跨尺度结构之间的联系;该模块能够重点强化车辆、舰船、飞机、建筑等目标的边缘、转角和弯曲轮廓,改善小目标、密集目标及旋转目标的特征完整性与定位稳定性,并通过可靠性门控抑制噪声和伪边缘,通过标准注意力与曲率注意力融合避免平坦区域被过度增强。

AI魔改博士-中大博士 46

11、ThingsBoard集群部署k8s

今天终于有时间去搞这个啦,拖了很久了,一直没时间,因为我本地没有那么多机器资源,开虚拟机不够,如果租用阿里云服务器,需要有充值的时间,因为这个费用是按小时付费,需要有连贯的时间来搞才行,今天恰好有时间,就开始搞了,弄成功搞出来了,特地写博客记录下来。

AldrichEugene 990

unix环境高级编程之 read与write 函数详解

学习记录:unix环境高级编程之 read 与write  函数详解 备注:本博文非本人所写,本人觉得此文讲的非常地道通俗易懂,所以摘录在此以方便以后再次查看 read函数从打开的设备或文件中读取数据。 #include ssize_t read(int fd, void *buf, size_t count); 返回值:成功返回读取的字节数,出错返回

chen 8401

PyQt(Python+Qt)学习随笔:PyQt界面派生类构造方法中super方法的使用

老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在《第15.7节 PyQt入门学习:PyQt5应用构建详细过程介绍》和订阅专栏《第二章、PyQt5应用构建详细过程介绍》中,老猿介绍界面派生类的构造方法如下: class MediaPlayerWin(QtWidgets.QWidget,Ui_UI_PlayerWin): def __i...

老猿Python 2711

UNIX 环境高级编程之带缓冲 I/O 与不带缓冲 I/O 的区别

1、I/O I/O 操作可根据是否带缓冲区来分类为带缓冲的 I/O 和不带缓冲区的 I/O ,后者就是标准 I/O。 那么这两者有啥区别呢? 不带缓冲其实就是应用程序直接使用系统调用。 标准 I/O 是在系统调用上做了一层封装,替用户做了相关优化操作,从而减少应用程序的系统调用次数,从而达到一定的性能优化。 比如需要写 100 字节数据到磁盘文件。 内核的缓冲大小为 100 字节,假设用户不知道内...

chuanglan的专栏 516

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

第十二章_高级I/O_《UNIX环境高级编程(第三版)》_笔记

存储映射I/O(mmap):零拷贝高效I/O,适合大文件读写和进程间共享内存,核心是。I/O多路复用:select(跨平台、低并发)、poll(无fd上限)、epoll(Linux高并发首选),核心是“监听多fd就绪事件”。记录锁:通过fcntl实现文件/记录级锁,解决多进程冲突,共享锁与排他锁互斥。异步I/O(AIO):非阻塞发起I/O,通过信号或回调通知完成,适合多I/O任务并行。信号驱动I/O:SIGIO通知I/O就绪,信号处理函数中完成I/O,适用于低速设备和socket。

C/C++ 628

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

《UNIX环境高级编程》IO模块超详细

文件打开的标记信息(FILE *类型的结构体指针变量)

iamXiaolan 1255

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

第三章_文件I/O_《UNIX环境高级编程(第三版)》_笔记

原子操作:多步操作一次性完成,中间不可中断,避免其他进程干扰——UNIX文件I/O中解决并发冲突的核心手段。用核心I/O函数(open/read/write/lseek/close)完成基础操作,注意返回值判断和循环读写。优化效率:缓冲区大小设为磁盘块大小(4096),避免频繁系统调用。并发安全:用原子操作(O_APPEND/pread/pwrite/O_CREAT+O_EXCL)避免冲突。灵活控制:用dup/dup2重定向fd,用fcntl修改标志,用fsync保证数据安全。

C/C++ 678

UNIX 环境高级编程第三章

例如,i节点包含了文件的所有者,文件长度,文件所在设备,指向文件实际数据块在磁盘上所在位置的指针等等。具体处理方式与文件系统的实现有关,当定位超出文件尾端之后写时,对于新写的数据需要分配磁盘块,但是对于源文件尾端和新开始写位置之间的部分则不需要分配磁盘块。文件偏移量可以大于文件的当前长度,在这种情况下,对该文件的下一次写将加长该文件,并在文件中构成一个空洞,这一点是允许的。每个进程都有自己的文件表项的一个理由:这种安排使每个进程都有它自己对该文件的当前偏移量。(2)内核为所有打开文件维持一张文件表。

weixin_74174531的博客 1191

UNIX环境高级编程——文件I/O

UNIX环境高级编程——文件I/O

qq_38154295的博客 597

unix环境高级编程笔记(2)-- 文件I/O之不带缓冲的I/O

1 引言   不带缓冲区的I/O(unbuffered I/o)是指每个read 和 write 都调用内核中的一个系统调用,这些不带缓冲区的I/O 不是ISO C 的组成部分。 2 文件描述符   每个打开的文件都通过文件描述符引用,文件描述符是一个非负整数。open 和 create 函数返回的文件描述符供 read write 和 close 使用。 unix中文件描述...

143

《UNIX环境高级编程》Chapter3——文件I/O

有缓冲的IO,数据读写先经过用户空间的缓冲区,等缓冲区满了或手动刷新,才调用底层的系统调用;:没有缓冲的IO,每次进行读写,直接发起系统调用;二者的区别在于有缓冲的IO进行系统调用的次数明显少于无缓冲IO,从而效率更高;本文要讲的文件IO属于无缓冲的IO。

2301_80345648的博客 918

UNIX环境高级编程学习之路(一)----文件I/O

对于UNIX环境编程,工作中经常会用到相关知识,作为学习UNIX环境编程的经典书籍--UNIX环境高级编程,是每个UNIX编程人员必看的经典书籍之一,为了将相关知识重新进行学习,以系统的整合所学知识,遂以博文形式作为总结。 一、概述     Unix系统可用的文件I/O函数--打开文件,读文件,写文件等,大多数文件I/O只需用到5个函数:open、read、write、ls

程序员——驻酒客栈 866

Unix环境高级编程笔记(一)文件I/O

File I/O 文章目录File I/O介绍文件描述符(File Descriptors)open 和 openat 函数 介绍 我们通过描述文件I / O可用的函数来开始对UNIX系统的讨论——打开文件、读取文件、编写文件,等等。在UNIX系统上,大多数文件I/O只能使用5个函数来执行:open、read、write、lseek和close。 然后,我们将研究各种缓冲区大小对读写函数的影响。...

TB_Master的博客 337

UNIX环境高级编程 学习笔记 第三章 文件I/O

UNIX系统大多数文件IO只用open、read、write、lseek、close。 不带缓冲的IO指每个read和write都调用内核中的一个系统调用,不带缓冲的IO不是ISO C的组成部分,但是POSIX.1和SUS的的组成部分。 对内核而言,所有打开的文件都通过文件描述符引用,当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。open、creat返回文件描述符标识该文件,可将其作为参数传递给read和write。 UNIX的shell通常把文件描述符0与进程标准输入关联,文件描述符

tus00000的博客 609

UNIX环境高级编程习题——第三章

第三章习题3.1 当读/写磁盘文件时,本章中描述的函数确实是不带缓冲机制的吗?请说明原因:1、本章中描述的read和write函数都是系统调用,这两个函数都是在内核中进行的,所以是不带缓冲的I/O函数。而带有缓冲机制的函数是以内存空间作为缓冲区,避免不当操作降低多写性能。3.2 编写一个与3.12节中dup2功能相同的函数,要求不掉用fcntl函数,并且要有正确的出错处理:这里写代码片3.3 假设一

kingolie的博客 2565

Unix环境高级编程之文件I/O

文章目录函数open和openatcreate函数close函数lseek函数read函数write函数文件共享原子操作dup和dup2函数sync、fsync和fdatasync函数fcntl函数/dev/fd Unix环境下,可以通过Posix提供的一组不带缓冲的I/O完成文件相关I/O。 函数open和openat 调用者两个函数可以创建或者打开一个文件。 #include &amp;lt;fcnt...

liudonghai11的博客 291
上一篇: 【UNIX环境高级编程】【详细解析用open打开的文件数据结构】
小钢炮0
博客等级 码龄6年 10粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值