文件IO_文件截断_ftruncate,truncate(附Linux-5.15.10内核源码分析)

目录

1.为什么需要文件截断?

2.truncate函数介绍

2.1 truncate函数

2.2 truncate函数内核源码分析

2.3 truncate函数使用示例

3.ftruncate函数介绍

3.1 ftruncate函数

3.2 ftruncate函数内核源码分析

3.3 ftruncate函数使用示例

3.4 ftruncate和文件偏移量的关系?

4.ftruncate和truncate区别


1.为什么需要文件截断?

文件截断是指将文件的长度截断为指定大小或者完全清空文件内容。在操作系统中,文件通常由一系列连续的数据块组成,每个数据块存储文件的一部分内容。通过执行文件截断操作,可以修改文件的大小或清空文件内容。

在执行文件截断操作时,需要注意以下几点:

  • 如果截断后的文件大小小于原始大小,那么超出截断长度的部分内容将被删除。
  • 如果截断后的文件大小大于原始大小,那么新增部分的内容将会以空字符填充。
  • 需要有适当的权限来执行文件截断操作,否则可能会失败。

2.truncate函数介绍

2.1 truncate函数

#include <unistd.h>
#include <sys/types.h>int truncate(const char *path, off_t length);

函数简介:truncate函数是一个用于文件截断的系统调用函数,在C语言程序中使用。该函数可以根据指定的大小截断文件,使其变为指定大小或者完全清空文件内容。

函数参数:

path:是要截断的文件路径。

length:要截断的目标大小。

函数返回值:

成功:返回0。

失败:失败返回-1,并设置errno。

2.2 truncate函数内核源码分析

图 2-1 truncate函数内核源码调用流程

truncate函数通过文件路径名(pathname)获取struct path对象,struct path记录了inode信息,进行文件截断之前需要做一些异常判断,比如:inode是否是普通文件,inode是否有写权限,是否是追加模式等等,通过异常检测后,需要设置inode新属性,新属性包括文件大小等信息,再通过notify_change函数通知inode完成新属性同步,从而完成文件截断。

2.3 truncate函数使用示例

int truncate_test() {int ret = truncate(TEST_FILE, 120);if (ret == -1) {perror("truncate error");return -1;}return 0;
}

3.ftruncate函数介绍

3.1 ftruncate函数

#include <unistd.h>
#include <sys/types.h>int ftruncate(int fd, off_t length);

函数简介:ftruncate函数是一个用于文件截断的系统调用函数,它可以在C语言程序中使用。该函数通过文件描述符来操作文件,将文件截断为指定的大小。

函数参数:

fd:文件描述符。

length:要截断的目标大小。

函数返回值:

成功:返回0。

失败:失败返回-1,并设置errno。

3.2 ftruncate函数内核源码分析

图 3-1 ftruncate函数内核源码调用流程

ftruncate函数内核调用流程和和truncate函数相似,不同点在与ftruncate函数通过fdget函数获取struct file对象,struct file对象有inode记录信息,通过struct file对象完成inode新属性修改,从而完成文件截断。

3.3 ftruncate函数使用示例

#define TEST_FILE "/tmp/test.txt"void print_buf(unsigned char *buf, int len) {if (len <= 0) {printf("error len:%d\n", len);return;}for (int i = 0; i < len; i++) {printf("%c%02X ", ((i % 16) || (i == 0)) ? : '\n', buf[i]);}printf("\n");
}void print_pos(int fd) {int pos = lseek(fd, 0, SEEK_CUR);printf("cur pos:%d\n", pos);
}int read_len_data(int fd, unsigned int len) {if (len > READ_BUF_SIZE) return -1;char rbuf[READ_BUF_SIZE] = {0};int ret = read(fd, rbuf, len);print_buf((unsigned char *)rbuf, ret);return ret;
}int write_len_data(int fd, unsigned char len, char ch) {unsigned char sbuf[BUF_SIZE] = {0};for (unsigned char i = 0; i < len; i++) {sbuf[i] = ch;}int ret = write(fd, sbuf, len);if (ret == -1) {perror("write error");return -1;}return 0;
}int ftruncate_test() {int fd = open(TEST_FILE, O_RDWR | O_CREAT, 0644);if (fd == -1) {perror("open error");return -1;}write_len_data(fd, 100, 'a');int ret = ftruncate(fd, 20);if (ret == -1) {perror("ftruncate error");close(fd);return -1;}print_pos(fd);lseek(fd, 0, SEEK_SET);read_len_data(fd, 1000);close(fd);return 0;
}

3.4 ftruncate和文件偏移量的关系?

ftruncate函数不会改变文件偏移量。可以分为两种情况讨论:

  • 情况1:ftruncate截断文件,文件长度变小,文件偏移量还是保留上一次记录,即使文件长度变为0,文件偏移量依然保持不变。
  • 情况2:ftruncate填充文件,文件长度变大,文件偏移量还是保留上一次记录。

从ftruncate内核源码分析,ftruncate未修改文件偏移量(f_pos)的值,所以ftruncate不影响文件偏移量。

4.ftruncate和truncate区别

 图 4-1 ftruncate和truncate区别

如图4-1,truncate和ftruncate共同点都是修改struct inode属性。不同点是两者采用的路径不一样,

ftruncate函数通过使用fd映射struct file对象,再通过struct file对象查找到inode实例,从而修改inode实例。

truncate函数没有fd参数,采用文件路径名获取struct path(路径结构)对象,再通过struct path对象获取inode实例,从而修改inode实例。

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

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

相关文章

进程间通信之共享内存

共享内存 1.共享内存的概念2.共享内存函数2.1 shmget函数2.2 shmat函数2.3 shmdt函数2.4 shmctl函数 3. 共享内存的使用 1.进程间通信的分类&#xff1a; &#xff08;1&#xff09;管道&#xff1a;1、匿名管道pipe;2、命名管道mkfifo &#xff08;2&#xff09;System V IPC&…

跨境电商中的安全利器与效率助推器

在如今全球互联网时代&#xff0c;跨境电商已成为全球贸易的重要组成部分。然而&#xff0c;对于从事跨境电商的企业和个人而言&#xff0c;面对诸多网络隐私与安全风险&#xff0c;如何确保在线操作的安全性和高效性成为了摆在他们面前的重要课题。本文将向您介绍隐擎Fox指纹浏…

从Spring 应用上下文获取 Bean

ApplicationContext 提供了获取所有已经成功注入 Spring IoC 容器的 Bean 名称的方法 getBeanDefinitionNames() 。然后我们可以借助于其 getBean(String name) 方法使用 Bean 名称获取特定的 Bean。 我们使用 CommandLineRunner 接口来打印一下结果。 1.1 获取所有的 Bean im…

手机APP智能硬件开发,蓝牙设备如何测试?

一、APP扫描设备 1、手机端蓝牙不同设置下是否能正常扫描&#xff1a;蓝牙打开、蓝牙关闭&#xff1b; 2、蓝牙设备被扫描到并出现在可连接设备列表的条件&#xff1a; 蓝牙设备名称与可连接的设备列表中的名称匹配、设备处于广播状态&#xff1b; 蓝牙设备与可连接的设备列…

【前端技巧】CSS常用知识碎片(九)

CSS常用知识碎片&#xff08;九&#xff09; mask-image属性 带有半透明的PNG图像的遮罩效果 .mask-image {mask: no-repeat center / contain;mask-image: url(bird.png); }SVG图形遮罩效果 .mask-image {mask-image: url("data:image/svgxml,%3Csvg viewBox0 0 3232…

mysql 字符 1024个字符限制 cast转为varchar 不限制字符长度 最大字符长度 group_concat长度限制

设置group_concat的最大长度然后再运行 SET SESSION group_concat_max_len102400;

【算法基础:数据结构】2.2 字典树/前缀树 Trie

文章目录 知识点cpp结构体模板 模板例题835. Trie字符串统计❤️❤️❤️❤️❤️&#xff08;重要&#xff01;模板&#xff01;&#xff09;143. 最大异或对&#x1f62d;&#x1f62d;&#x1f62d;&#x1f62d;&#x1f62d;&#xff08;Trie树的应用&#xff09; 相关题目…

C# MVC 多图片上传预览

一.效果图&#xff1a; 开发框架&#xff1a;MVC&#xff0c;Layui 列表主界面这里就不展示了&#xff0c;可以去看看这篇文章&#xff1a;Layui项目实战&#xff0c;这里讲的是“上传Banner”界面功能&#xff1a; 其中包括&#xff0c;多文件上传&#xff0c;预览&#xff0c…

vue进阶-消息的订阅与发布

&#x1f4d6;vue基础学习-组件 介绍了嵌套组件间父子组件通过 props 属性进行传参。子组件传递数据给父组件通过 $emit() 返回自定义事件&#xff0c;父组件调用自定义事件接收子组件返回参数。 &#x1f4d6;vue进阶-vue-route 介绍了路由组件传参&#xff0c;两种方式&…

【conan】本地编译三方库,上传conan服务器

1.6 conan 远程已经编译好的库 conan中文博客&#xff1a; 三方库资源&#xff1a; github conan-io 本地查询 conan search Existing package recipes:b2/4.9.6 boost/1.71.0nolovr/stable bzip2/1.0.8 ceres-solver/2.0.0nolovr/stable eigen/3.3.7nolovr/stable eigen_c…

【软件测试】selenium中元素的定位

1.元素的定位 不管用那种方式&#xff0c;必须保证页面上该属性的唯一性 1.CSS 定位 CSS(Cascading Style Sheets)是一种语言&#xff0c;它被用来描述HTML 和XML 文档的表现。 CSS 使用选择器来为页面元素绑定属性。这些选择器可以被selenium 用作另外的定位策略CSS的获取可…

Go 工具链详解(三): 代码测试神器 go test

go test 作用 go test 是 Go 工具链中的一个命令&#xff0c;用于编译和运行按照要求编写的 Golang 测试代码&#xff0c;并生成测试报告。 要求将测试代码所在的文件命名为 *_test.go&#xff0c;如此命名的文件不会被 go build 命令编译&#xff0c;但是会被 go test 进行编…

C++基础算法前缀和和差分篇

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;C算法 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 主要讲解了前缀和和差分算法 文章目录 Ⅳ. 前缀和 和 差分Ⅵ .Ⅰ前缀和…

echarts_柱状图+漏斗图

目录 柱状图(bar)需求[1] 复制案例[2] 修改类目轴方向[3] 修改数据渲染方向[4] 修改坐标轴文本样式 漏斗图(funnel)漏斗图的形状 柱状图(bar) 需求 如上图&#xff0c;做一个横向柱状图&#xff0c;后端返回的数据是从小向大排列的数据&#xff0c;希望能够按照顺序进行展示。…

【Docker】详解docker安装及使用

详解docker安装及使用 1. 安装docker1.1 查看docker版本信息 2. Docker镜像操作3. Docker容器操作4.知识点总结4.1 docker镜像操作4.2 docker容器操作4.3 docker run启动过程 参见docker基础知识点详解 1. 安装docker 目前Docker只能支持64位系统。 ###关闭和禁止防火墙开机自…

pytorch+CRNN实现

最近接触了一个仪表盘识别的项目&#xff0c;简单调研以后发现可以用CRNN来做。但是手边缺少仪表盘数据集&#xff0c;就先用ICDAR2013试了一下。 结果遇到了一系列坑。为了不使读者和自己在以后的日子继续遭罪。我把正确的代码发到下面了。 1&#xff09;超参数请不要调整&am…

Android oom_adj 详细解读

源码基于&#xff1a;Android R 0. 前言 在博文《oom_adj 内存水位算法剖析》一文中详细的分析了lmkd 中针对 oom_adj 内存水位的计算、使用方法&#xff0c;在博文《oom_adj 更新原理(1)》、《oom_adj 更新原理(2)》中对Android 系统中 oom_adj 的更新原理进行了详细的剖析。…

Linux Shell脚本文件

文章目录 Linux Shell脚本文件vim编辑器vi的使用 认识Bash变量环境变量用户操作变量delcare与typeset 命令的别名与历史命名 正则表达式Shell ScriptsShell Scripts良好习惯第一个shell其他shell例子 - 来自鸟哥linux私房菜语法介绍shell 的调试 Linux Shell脚本文件 vim编辑器…

Centos 7 安装 Oracle 11G

Oracle 11G 安装教程 准备环境 p13390677_112040_Linux-x86-64_1of7.zipp13390677_112040_Linux-x86-64_2of7.zipCentos 7- rhel7-英文版的系统–不想换语言的执行(LANGen_US)– 传输 文件到服务器上 创建用户和组 [rootlocalhost ~]# groupadd oracle [rootlocalhost ~]…

20230715----重返学习-vue3新API-Vue3和Vue2对比-vue3语法-Vue3编码

day-113-one-hundred-and-thirteen-20230715-vue3新API-Vue3和Vue2对比-vue3语法-Vue3编码 vue3新API Vue 3 迁移指南 虚拟DOM 说明:看01视频。虚拟DOM是用于让vue核心代码脱离浏览器的限制&#xff0c;在微信小程序、手机端、canvas之类也有能使用vue语法的可能&#xff0…