文件小注意

news/2024/5/7 20:56:58/文章来源:https://blog.csdn.net/wwwyue1985/article/details/130039526

目录

0 前言

1 标识 O_CREAT O_APPEND

2 ftruncate与truncate

3 O_DIRECT与O_DSYNC、O_SYNC

4 open与fopen

5 关于mmap


0 前言

文件操作在软件开发中是很常见的一件事。虽然与它相关的工作看起来不怎么起眼,无非就是通过通过open、read、write、close几个调用搞定的事情,但也正是这种看似简单的工作,在稍加变化需求的场景中,会给你带来意想不到的麻烦。这里就记录本人最近关注到的几个点,做为小例子,分享给大家。

多说一句,往往简单的事情会给人带来大麻烦,就是因为人的大脑会对简单或者认为简单的事情过于麻痹大意,先入为主,不加重视,导致往往只看到冰山一角。该怎么做,不用多说了,直接看实例。(本文都是基于Ubuntu系统)

1 标识 O_CREAT O_APPEND

对于linux下的open调用,你敢说man里面的这些flags你都清楚了?

如果路径下未有文件,就需要O_CREAT标识,否则open就会失败。如果想让文件处于追加写的状态,则需要O_APPEND标识。这还是简单的标识,还有许多复杂标识等着我们深入了解。

man手册对于系统调用都有详尽的说明,很多人其实是比较抗拒看man手册的,往往通过百度了解一下接口的使用,就开始调用了。这主要是man手册为英文写成,很多时候搞清楚一个接口需要花比较多的时间,另外个别语句还可能比较绕口,有时候琢半天也不明白意思,这个时候不如直接百度来的称手。但是这些都是初期的阵痛与障碍,时间长了,就会习惯,而且效率也会变高不少。

等等,有人可能会说,man open的时候,看不到关于open接口的说明。这个时候,需要安装一下,apt install manpages-dev

关于man的使用,可以参考博主之前的一篇文章:https://blog.csdn.net/wwwyue1985/article/details/123929554

2 ftruncate与truncate

使用open调用创建文件后,文件大小为零。这个时候,如果通过mmap建立文件映射,那么写文件内存会失败(会报Bus error的错误)。同样,如果文件大小不够,写范围超过文件大小时,也会失败。也就是说,文件大小不会随着写内容的增加而增大。貌似window倒是支持这一点,神奇吧。此时,我们可以通过ftruncate来扩展文件大小。如果查看man手册,我们会发现另外一个接口truncate。二者有什么区别呢?

通过手册,可以看到,使用ftruncate时,文件必须打开,且支持写入;使用truncate接口,文件必须是可写的。

3 O_DIRECT与O_DSYNC、O_SYNC

操作系统为了提高文件读写性能,特别是像磁盘这种不支持随机读写的设备(需要旋转盘面和移动磁头),往往会在内存中开辟一片缓冲区。写入文件的内容不会立即写入硬件设备,而是先写到文件的缓冲区,当攒够一定量或者满足某些特征(也可能是内核自己排序,使得对硬件设备的访问尽可能有序)之后,才会触发写设备,以此来提高落盘性能。但有时候,我们又想让写入文件的内容立即同步到磁盘等硬件设备(比如一些关键的日志或者元数据),以免意外事件(比如断电)导致关键信息丢失或文件不可用。此时,O_DIRECT标识就需要登场了。使用O_DIRECT标识意味着写文件的数据会同步传输到硬件设备:

但如果我们看man手册,会发现有相似功能的其他标识,比如O_DSYNC、O_SYNC:

这几个标识有什么区别呢?根据man手册说明,上面两个sync标识跟direct标识的差异主要在是不是同步文件元数据。什么是文件元数据?内核为了管理文件,需要一些辅助数据,比如文件的名称、大小、创建时间、磁盘位置等等,这些都不是文件内容本身的数据,而是为了管理文件所需的数据,这类数据就是元数据。当我们向文件写入内容的时候,文件的元数据可能就会发生变化,使用这里的带sync的两个标识,则操作系统不仅帮我们同步文件本身的内容,也同步文件相关的元数据。

那有人可能就又问了,同样是支持同步元数据,O_DSYNC和O_SYNC又有什么区别呢?根据man手册说明,O_DSYNC仅同步与输出数据相关的元数据,而O_SYNC同步文件相关的元数据。所以从集合的角度来看,应该是O_SYNC包含O_DSYNC,O_DSYNC包含O_DIRECT的关系。

4 open与fopen

我们平时操作文件时,会发现有两套类似的接口,open与fopen。它们的使用上有一些差别,很多人往往是通过网络复制一份代码,简单改改就使用,可能没有细究过open与fopen有什么区别。其实,fopen是C库提供的接口,而open是系统调用。从可移植性的角度来看,fopen的通用性更强(一些不支持操作系统的嵌入式系统中也支持,比如xilinx就自己提供了一套文件库,可以在裸机程序中使用上述fopen类接口)。但是在Linux下,fopen最终也是通过open这个系统调用实现的。Open类接口不仅支持普通文件,还支持被系统抽象为文件的所有东西,比如各种各样的设备。这样描述,大家是不是就清楚了。

5 关于mmap

额外补充一点,关于文件mmap映射的。用户空间看到的是(接口返回值)进程虚拟地址空间的一个虚拟地址,内核帮我们建立了页表并完成了物理地址到虚拟地址的映射。当我们将数据写入这个虚拟地址时,就相当于写入文件在内存的缓冲区。同步后,数据就体现到硬件上最终的文件中。基于这一点,我们可以在用户空间,对文件访问进行专门的优化。

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

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

相关文章

【MySQL】主从复制过程(实践)

1.安装好2台数据库服务器的系统,然后安装好MySQL软件 [rootjd-mysql ~]# mysql --version mysql Ver 14.14 Distrib 5.7.40, for linux-glibc2.12 (x86_64) using EditLine wrapper[rootjd-mysql-2 ~]# mysql --version …

第03章_用户与权限管理

第03章_用户与权限管理 1. 用户管理 ​ MysQL用户可以分为普通用户和root用户。root用户是超级管理员,拥有所有权限,包括创建用户 、删除用户和修改用户的密码等管理权限;普通用户只拥有被授予的各种权限。 MysQL提供了许多语句用来管理用户账号&#…

认识C++字符串复合类型

目录 前言: 1.数组 1.1C的数组 1.2C数组初始化 *2.字符串 2.1字符串与数组 2.2字符数组的存储 2.3字符串输入cin 2.4cin.getline() 2.5cin.get() 2.6函数重载例子 2.7混合输入数字和字符串 前言: C与C语言在内容上有些是一样的,也…

Zooker配置与测试

目录 1.介绍 2.配置 1.配置准备 2.配置修改 3.测试 1.介绍 2.配置 1.配置准备 zookeeper官网:Apache ZooKeeper (1)安装 JDK (2)拷贝 apache-zookeeper-3.5.7-bin.tar.gz 安装包到software目录下 (3)解…

mysql常用的基础命令

通过学习mysql命令提高数据处理和工作效率 基础命令 1.登录MySQL mysql -u root -p 2.查看当前系统所有数据库 show databases; 3.切换数据库 use 数据库名称 4.查看数据库下的所有表 show tables; 5.查看表结构; desc 表名; 6.创建数据库 crea…

CentOS7的下载、安装和配置(详细图解)

CentOS7安装包的下载 Centos7的安装包可以去官网(https://www.centos.org/)下载,但速度比较慢。 也可以用搜索引擎搜索国内镜像站点的安装包文件与官网同步,下载的速度非常快。 CentOS7软件安装包的分享 百度网盘分享&#xff…

python函数详解_INDEX函数

一. 函数的作用 函数就是将一段具有独立功能的代码块 整合到一个整体并命名,在需要的位置调用这个名称即可完成对应的需求。 函数在开发过程中,可以更高效的实现代码重用。 二. 函数的使用步骤 1. 定义函数 def 函数名(参数):代码1代码2...... 复制 …

usb_cam相机录制rosbag

文章目录运行环境:1.1 usb_cam连接:1.2 usb-cam启动1.2 查看相机话题名称2.1 rosbag录制2.2 播放rosbag运行环境: ubuntu20.04 noetic 杰瑞微通usb_cam(分辨率640x480) 宏基暗影骑士笔记本 1.1 usb_cam连接&#xff…

Golang每日一练(leetDay0030)

目录 88. 合并两个有序数组 Merge Sorted Array 🌟 89. 格雷编码 Gray Code 🌟🌟 90. 子集 II Subsets II 🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/…

Linux复习 / 进程控制QA梳理

文章目录前言Q&A进程终止Q:exit和_exit的区别?Q:内核是如何终止进程的?进程等待Q:为什么要等待子进程?Q:如何等待子进程(wait/waitpid的区别)?进程替换Q&…

TCP协议工作机制二(滑动窗口,流量控制,拥塞控制,延时应答,捎带应答等)

目录 滑动窗口 流量控制 拥塞控制 延时应答 捎带应答 面向字节流 异常情况 UDP和TCP对比 滑动窗口 由于TCP是可靠传输,有确认应答,超时重传,连接管理等机制,发送消息时需要等待接收方返回的ack.因此会消耗大量等待ack的时间,我们引入滑动窗口的机制来竭尽可能提高TCP的…

【Linux】环境变量进程虚拟地址空间

环境变量&进程虚拟地址空间环境变量一些常见的环境变量-PATH修改环境变量进程虚拟地址空间环境变量 使用ls man pwd cd echo 这些指令时,不需要加./但是要运行我们自己的可执行程序就需要加上,本质上两个都是指令,为什么执行方法不同&am…

python学习之http客户端和服务端

Part1前言python非常简洁,非常适合写小功能以及测试接口。本文主要记录用pyhon实现一个简单的http客户端和服务端。Part2http客户端这里采用request库来实现。示例如下import requests import json url http://127.0.0.1:81/test?key1123&key2456headers {Au…

代码不熟没关系,让AI替你写

程序员早已不是一个陌生的群体,但程序、代码相对普通人而言,看着还是比较深奥难懂,但自从有了ChatGPT,不少对此有兴趣的外行人士,也能轻松写出代码了,比如让ChatGPT写一个贪吃蛇游戏,按它给出的…

【如何使用Arduino控制WS2812B可单独寻址的LED】

【如何使用Arduino控制WS2812B可单独寻址的LED】 1. 概述2. WS2812B 发光二极管的工作原理3. Arduino 和 WS2812B LED 示例3.1 例 13.2 例 24. 使用 WS2812B LED 的交互式 LED 咖啡桌4.1 原理图4.2 源代码在本教程中,我们将学习如何使用 Arduino 控制可单独寻址的 RGB LED 或 …

ROS实践05 订阅方实现Python

文章目录运行环境:思路:1.1 Python代码实现1)工作空间创建和编译2)功能包创建和添加依赖3)新建.py文件4)修改CMakeList5)运行节点运行环境: ubuntu20.04 noetic 宏基暗影骑士笔记本…

Java每日一练(20230409)

目录 1. 多数元素 🌟 2. 反转链表 II 🌟🌟 3. 日期之间的遍历 🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 多数元素 给定一个…

使用红黑树封装map和set

目录 一、set和map的底层结构 使用模板区分map和set 使用仿函数来比较大小 二、红黑树中set和map的迭代器 end和begin迭代器 operator迭代器 operator-- 三、set与map中的迭代器和const迭代器 四、迭代器的拷贝构造 五、完整代码 set.h map.h RBTree.h 一、set和ma…

UE4 C++编写自定义动画蓝图节点

UE中自带的动画蓝图节点有限,在实现一些功能时需要通过C编写一些自定义的动画蓝图节点,本文就来讲解其基础实现,自定义节点最终效果如下: 源文件下载:https://download.csdn.net/download/grayrail/87654290 1.流程简…

linux 服务器 docker 安装 mysql 8.0.32 常用命令

我的Docker专栏 https://blog.csdn.net/weixin_45580378/category_12276045.html docker 镜像 https://registry.hub.docker.com/_/mysql/tags 1.版本号可不写 不写就是最新版本 最好写上 docker pull mysql:版本号2.查看镜像是否安装成功 如下图 docker images3.创建文件…