首页 > 其他分享 >简单的磁盘文件IO

简单的磁盘文件IO

时间:2024-09-12 21:24:21浏览次数:1  
标签:count 文件 字节 写入 描述符 IO 磁盘 打开

文件描述符

在linux中,文件IO的系统调用,是 以文件描述符,即一个非负整数,来指代打开的文件,你可以认为,操作文件描述符就是在操作文件

并且,对于每个进程而言,他们的文件描述符是自成一套的

以下截图是为了验证每个进程的文件描述符自成一套,我们可以看到有左边两个程序,t1.c和t2.c,他们几乎是一样的,不同的是打印的名称以及打开的文件不同,然后右边是他们执行的结果,可以看到他们打开的文件描述符是相同的

1

以下是标准描述符

2

标准描述符其实就和编程中的关键字类似,是系统已经提前定义好的,分别是标准输入,标准输出,标准错误,这三个是基本上shell启动时就会打开了,然后他们的值分别是0,1,2

打开的文件一般是有上限的,比如最多同时打开1024个文件,这样的话,文件描述符的取值就是0-1023,基于这一点,文件描述符的值一般是 最小的可用的,比如我们之前打开的文件描述符是3,因为0,1,2这三个已经被用了,所以3就是 最小的可用的值

这里我们可以再来实验下,比如我关掉标准错误,然后在打开一个文件,看看它的文件描述符是多少

我们可以看到,当我们关掉标准错误在打开一个文件时,这时候的文件描述符就是2了,因为打开前只有0和1在使用,所以2就是最小的可用的值

2

磁盘文件IO的系统调用(函数)

主要就是4个吧,我们可以通过man命令对这些系统调用进行查看,右边终端就是输入的命令,左边是呈现的结果,按q退出,例如下面这张图

3

  • open函数:打开一个文件,以 flags 的方式打开 pathname 文件,或者赋予创建文件 mode 的权限并以 flags 的方式打开它

       函数声明
       int open(const char *pathname, int flags);
       int open(const char *pathname, int flags, mode_t mode);
    

    参数介绍

    • pathname: 这里就是打开文件的路径名
    • flags: 这个是文件打开的标志,简单来说就是你要用什么方式打开这个文件,只读、只写、可读可写等等
    • mode: 这个是创建文件的文件权限,就是如果说你要创建这个文件,你要给他什么权限

    返回值:返回的就是文件描述符啦,一个整数

  • read函数:从指定文件中读取数据,从 fd 中一次最多读取 count 字节的数据到缓冲区 buf

      函数声明
      ssize_t read(int fd, void *buf, size_t count);
    

    参数介绍:

    • fd: 这个是要进行读取的文件的文件描述符
    • buf: 这个是存储读取数据的地方
    • count: 表示一次最大的读取数

    返回值:返回的是读取的字节数(不一定和count相等)

    需要注意的是,有时候我们可能想以字符串的方式打印读取的数据,这时候记得要给缓冲区buf最后加上一个 空字符\0 用以表示字符串的结束(虽然不加好像也问题)

  • write函数:向指定文件中写入数据,从缓冲区 buf 中向 fd 一次写入最多 count 字节的数据

      函数声明
      ssize_t write(int fd, const void *buf, size_t count);
    

    参数介绍:

    • fd: 这个是要进行写入的文件的文件描述符
    • buf: 这个是存储写入数据的地方
    • count: 表示一次最大的写入数

    返回值:返回的是写入的字节数(不一定和count相等)

    需要注意的是

    对磁盘文件执行 I/O 操作时,write()调用成功并不能保证数据已经写入磁盘。因为为了减少磁盘活动量和加快 write()系统调用,内核会缓存磁盘的 I/O 操作

  • lseek函数:改变文件的偏移量,决定了文件IO的开始位置

      函数声明
      off_t lseek(int fd, off_t offset, int whence);
    

    先说一下什么是文件偏移量,我们可以简单的理解为文件打开时光标的位置,这样我们读取或者写入都是从光标开始向文件后方进行,

    参数介绍:

    • fd: 这个是要进行操作的文件的文件描述符
    • offset: 这个是要改变的偏移量大小,可正可负
    • whence: 这个表示从文件的什么位置开始改变,以下是whence的值
      7

    返回值:返回的是从文件开头开始算起的文件偏移量

5

这里给一些lseek的例子,可以让你更好的理解
6

文件空洞

事实上,文件偏移量的改变是会改变文件的表面大小的,但不会影响磁盘上的大小

比如说,文件test.txt有三个字节的内容,现在你让他偏移100个字节,这个文件的表面大小就会增长到100字节,但磁盘上的大小还是三字节,这些增长的东西就是文件空洞了,文件空洞是不会占用磁盘空间的

以下是一个例子,左边是创建一个文件,然后刚开始是0字节,我们用一个函数先是把它的偏移量设置为10,然后写入abc三个字节的数字,这时候发现文件的大小是13字节,可是我们只写入了3字节的数据,然后打开文件,也就是右边的图,可以看到在abc,也就是我们实际写入的数据前,有一些文件空洞,这些就是文件偏移量造成的
8

标签:count,文件,字节,写入,描述符,IO,磁盘,打开
From: https://www.cnblogs.com/winter-z/p/18411024

相关文章

  • VisualStudio 2022 找不到内存 反汇编 寄存器调试工具
    本文将告诉大家如何解决在VisualStudio2022的调试-窗口里面找不到内存、反汇编、寄存器这三个调试工具的问题找不到的原因是没有启用地址级调试只需要在“工具”(或“调试”)>“选项”>“调试”中选择“启用地址级调试”然后进行调试即可看到开启之后,即可在调试-窗口......
  • Qml 实现仿前端的 Notification (悬浮出现页面上的通知消息)
    【写在前面】经常接触前端的朋友应该经常见到下面的控件:在前端中一般称它为Notification或 Message,但本质是一种东西,即:悬浮弹出式的消息提醒框。这种组件一般具有以下特点:1、全局/局部显示:它不依赖于具体的页面元素,可以在整个页面的任意位置显示。2、自动消失:默认情况下,......
  • 【影像组学pyradiomics学习笔记】png图像提取组学特征
    1、提取单张png图像组学特征示例:importSimpleITKassitkimportnumpyasnpimportmatplotlib.pyplotaspltfromradiomicsimportfeatureextractorimportosimportcv2defload_image(image_path):image=cv2.imread(image_path,cv2.IMREAD_GRAYSCALE)#......
  • Qml 实现仿前端的 Notification (悬浮出现页面上的通知消息)
    【写在前面】经常接触前端的朋友应该经常见到下面的控件:在前端中一般称它为Notification或 Message,但本质是一种东西,即:悬浮弹出式的消息提醒框。这种组件一般具有以下特点:1、全局/局部显示:它不依赖于具体的页面元素,可以在整个页面的任意位置显示。2、自动消失:默认情况下......
  • # sfc /scannow 检查修复系统遇到错误--Windows 资源保护找到了损坏文件但无法修复其
    sfc/scannow检查修复系统遇到错误–Windows资源保护找到了损坏文件但无法修复其中某些文件一、问题描述:在使用CMD命令sfc/scannow检查修复windows系统时,遇到错误:Windows资源保护找到了损坏文件但无法修复其中某些文件。CBS.Logwindir\Logs\CBS\CBS.log中有详细......
  • U盘文件及文件夹带锁修复
    磁盘管理修复工具Disks磁盘管理–针对U盘文件及文件夹带锁修复本文章只针对统信系统文章目录功能概述一、安装工具二、数据备份三、检查文件系统1.通过启动栏中的“磁盘”或者桌面的“磁盘”启动文件来启动应用:2.选择U盘设备3.点击“检查文件系统”按钮(......
  • Pod管理策略2(资源清单文件)
    1.污点策略尽量不调度:PreferNoSchedule不被调度:NoSchedule驱逐节点:NoExecute#设置污点标签[root@master~]#kubectltaintnodenode-0001k=v:NoSchedulenode/node-0001tainted#查看污点标签[root@master~]#kubectldescribenodesnode-0001Taints:k=......
  • Java 假设有一个对象list 有4列,4和3比较name 如果name不相同则记录4的version值string
    可以使用传统循环或Java8的流(Stream)API来实现这一逻辑。以下是这两种方法的示例代码:1.使用传统循环importjava.util.List;publicclassMain{publicstaticvoidmain(String[]args){List<MyObject>list=...;//初始对象列表String......
  • dotnet 测试在 UOS Linux 上使用 Process Start 打开文件的行为
    本文记录我在UOSLinux系统上使用Process.Start打开文件的行为使用UseShellExecute打开文本文件我放入了名为Test.txt的文件,然后使用下面代码尝试打开文件。实际测试可以正常打开usingSystem.Diagnostics;varfilePath="../Test.txt";Console.WriteLine($"文件......
  • VisualStudio 2022 如何显示 dotnet 6 及以上版本的框架的代码注释为中文
    官方现在只将中文注释维护到.NET5版本,没有为.NET6和.NET7和.NET8版本维护框架的中文注释。想要使用中文注释,需要使用第三方工具感谢https://github.com/stratosblue大佬提供的IntelliSenseLocalizer工具使用方法请参阅IntelliSenseLocalizer使用文档更多请参......