首页 > 其他分享 >进一步认识系统调用write()和read()

进一步认识系统调用write()和read()

时间:2024-09-18 17:23:44浏览次数:8  
标签:文件 调用 读取 字节数 read 偏移量 write 字节

简介

write 函数

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

  • fd:文件描述符,表示要写入的文件或设备
  • buf:指向要写入的数据的缓冲区
  • count:要写入的字节数
  • 返回值:成功时返回写入的字节数;失败时返回 -1

read 函数

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

  • fd:文件描述符,表示要读取的文件或设备
  • buf:指向存储读取数据的缓冲区
  • count:要读取的字节数
  • 返回值:成功时返回读取的字节数(可能小于 count);到达文件末尾时返回 0;失败时返回 -1

探究

write

  • write中count和buf的大小相等的情况下

    1

这样子是正常的,我们也正好像文件中写入了5个字节的内容,刚好就是world

这里r6表示显示6个字节的内容,R6表示以十六进制显示,s0是把文件偏移量设置为0

  • write中count比buf大小大1

    2

    我们可以看到,这还是正常,这是因为c语言中字符串是以空字节'\0'结尾,所以它在内存中实际的大小还要加上一个字节,换句话说,字符串所占用的字节数比长度大一,所以我们看到文件中的最后一个是一个未知的东西,这其实就是'\0',不过它是不可打印的

    我们也能看到r6显示出来最后一个是?,R6则更明显了,0x00其实就是空字节

  • write中count比buf大小大2及以上

    以下是大2的情况

    3

    ok,我们可以看到编译只是发出警告,没有报错,然后最后的一个字节就看内存的具体内容了

    以下是大3的情况

    4

    编译信息还是警告,不过我这里没有截取出来,可以看到最后一个字节是r

    大家还是要注意,就是这里没有报错不一定是绝对的,我们从未分配给我们的内存中读取数据会导致不在预期里的行为,比如这里的w和r两个字符,它根本就是取决于内存自己,然后我猜测没有报错只是因为我们访问的比较短,一般来说,分配的可用内存还是比较大的,不会刚好用完,还会留下一点可以使用的空间

    这里就要区分虚拟内存和物理内存了,总之大家注意不要越界就行

文件偏移量

它决定了文件io的开始位置

  • write
    5

    6

    我们可以看到,write调用后,文件偏移的改变量就刚好是写入的字节数(打开文件时,文件偏移量一般是0)

  • read

    可以看到当我们向文件中写入数据后,在直接读取,结果读取到的字节数是0,也就是没有读取到内容,这是因为写入数据后,文件偏移量就改变了,在进行读取就是从文件偏移量的位置开始读啦

    7

    这里我们在读取前,把文件偏移量设置为开头,也就是0,然后就读取2字节,文件总共有6字节,我们发现读取的字节数正好是2,没问题,可是把它用字符串的形式打印出来,可以看到wo正好是world的前两个字节,没错,可是后面是什么东西

    这是因为,字符串的结束要用空字节做标志,这里读取到的内容不是一个字符串,仅仅是两个字节,因为没有空字节,所以打印字符串就会出错

    8

    ok,我们这里手动给缓冲区加上空字节,然后在输出它,发现结果正确

    9

    我们这里可以看到,读取内容后,文件偏移量也发生改变了
    10

总结

  • write和read都会改变文件偏移量,而文件偏移量决定了io的开始位置

  • write需要注意申请写入的字节数count不要超过buf的大小,这会引发未定义的行为,read就没关系

  • 最后C语言中字符串是用空字节结尾的,所以实际大小比长度大1,然后read的内容不一定包括空字节,要打印的话,记得手动加上

标签:文件,调用,读取,字节数,read,偏移量,write,字节
From: https://www.cnblogs.com/dylaris/p/18414559

相关文章

  • Paper Reading: Deep forest auto-Encoder for resource-Centric attributes graph em
    目录研究动机文章贡献本文方法整体思想autoencoder预处理器深度森林编码生成器实验结果数据集和实验设置节点分类节点聚类用户推荐消融实验调参实验优点和创新点PaperReading是从个人角度进行的一些总结分享,受到个人关注点的侧重和实力所限,可能有理解不到位的地方。具体的细节......
  • 菜鸟笔记之PWN入门(1.1.2)C程序调用过程与函数栈变化(32位 vs 64位)(Intel)
    本文使用Intel的32位为例子进行举例。64位本质上和32位类似,主要区别在于函数参数的调用方式,文章结尾会简要提及。重新回顾一下栈pop和push指令//将0x50的压入栈push0x50//将esp指向的数据放入指定的寄存器中pop寄存器名字比如:popeax执行之后eax的值就变成了0x50......
  • 鹏哥C语言42---函数调用相关练习
    #define_CRT_SECURE_NO_WARNINGS#include<stdio.h>//------------------------------------打印1000-2000年之间的闰年---------------------------------------------------//闰年的判断规则有两个//1.能被4整除,但是不能被100整除//2.能被400整除也是闰年/*intmain(......
  • Java调用Apache commons-text求解字符串相似性
    前言    在之前的一篇漂亮国的全球的基地博客中,我们曾经对漂亮国的全球基地进行了一些梳理。博文中使用的数据来源,重点是参考以为博主分享的KML的数据,同时针对其国内的基地部署信息,我们从互联网百科的数据中搜寻到一些。其实拿到这两份数据的时候,是存在一些问题的,比如,KML的......
  • Spring Cloud全解析:服务调用之自定义Feign的配置
    自定义Feign的配置Feign的默认配置类是FeignClientsConfiguration,其内部定义了Feign默认使用的编码器、解码器、契约、重试机制等@Bean@ConditionalOnMissingBeanpublicDecoderfeignDecoder(){//解码器,将字节数组反序列化为方法返回值类型的对象,默认只支持反序列化为St......
  • C#里方法的怎么编写XML文档注释说明,用于调用时参数提示等
    一.什么是xml的注释?答:XML注解是一种用于描述XML文档结构和元素内容的标记语言。它是通过在XML文档中使用特殊的标记来定义文档结构和元素属性的。XML注解通常用于数据编码和数据交换的应用程序之间,以确保数据的一致性和互操作性。XML注解具有良好的可扩展性和可读性,因此它通......
  • android HandlerThread post后 7s才执行
    在Android中,HandlerThread是用来创建一个具有Looper的线程,这样可以在该线程上处理消息和运行任务。当你在HandlerThread上使用Handler的post()方法发送一个Runnable任务时,这个任务会被添加到MessageQueue中,并且会在Looper的主循环中被处理。如果你发现任务在post()之后大约7秒才被......
  • SQLSTATE[HY000] [2013] Lost connection to MySQL server at 'reading initial commu
    错误信息 SQLSTATE[HY000][2013]LostconnectiontoMySQLserverat'readinginitialcommunicationpacket',systemerror:111 翻译成中文为:在读取初始化数据包时失去到MySQL服务器的连接,系统错误111。通讯包初始化失败,估计是不允许连接访问引起的。解决办法以下是......
  • 织梦dedecms怎么调用图片集中图片的注释
    在DedeCMS中调用图片集中的图片及其注释,可以通过自定义函数或者利用已有的函数来实现。下面是一个基于已有资料的示例,展示如何调用图片集中的图片及其注释。首先,你需要确保你的图片已经被正确地添加到了织梦CMS的图集功能中。然后,你可以使用自定义函数来获取这些图片及其注释。......
  • C#外部调用bartender条码
    送bartender2016企业版,功能完整,能外部调用一维码,二维码,打印张数以及其他信息,引用seagull.bartender.print.dll文件调用打印            engine.Start();            stringluj="D:\打印模板\打印测试.btw";     ......