文件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.hqwc.cn/news/29510.html

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

相关文章

java学习路程之篇十、知识点、数组介绍、二维数组介绍、静态初始化、访问元素、遍历元素、动态初始化、内存图、数组常见问题

文章目录 01、数组介绍02、数组静态初始化03、数组元素访问04、数组遍历操作05、数组动态初始化06、数组内存图07、数组常见问题08、二维数组介绍09、二维数组静态初始化10、二维数组遍历11、二维数组动态初始化12、二维数组内存图 01、数组介绍 02、数组静态初始化 03、数组元…

Redis可视化工具(Redis Desktop Manager)

redis是我们平时开发工作中经常用到的非关系型数据库&#xff0c;常用于做数据缓存&#xff0c;分布式锁等。 为了更方便的使用redi&#xff0c;这里给大家推荐一款可视化工具&#xff1a;Redis Desktop Manager。 1.下载与安装 直接到gihub下载&#xff0c;地址 Release 0.…

Python分布式任务队列Celery

一、分布式任务队列Celery介绍 Python celery是一个基于Python的分布式任务队列&#xff0c;主要用于任务的异步执行、定时调度和分布式处理。它采用了生产者/消费者模式&#xff0c;通过消息中间件实现多个工作者进程之间的协作。 Python celery的架构主要包括以下组件&…

【图像处理OpenCV(C++版)】——5.6 图像平滑之联合双边滤波

前言&#xff1a; &#x1f60a;&#x1f60a;&#x1f60a;欢迎来到本博客&#x1f60a;&#x1f60a;&#x1f60a; &#x1f31f;&#x1f31f;&#x1f31f; 本专栏主要结合OpenCV和C来实现一些基本的图像处理算法并详细解释各参数含义&#xff0c;适用于平时学习、工作快…

【kubernetes系列】kubernetes之计算资源管理

资源类型 在 Kubernetes 中&#xff0c;Node 提供资源&#xff0c;而 Pod 使用资源。其中资源分为计算&#xff08;CPU、Memory、GPU&#xff09;、存储&#xff08;Disk、SSD&#xff09;、网络&#xff08;Network Bandwidth、IP、Ports&#xff09;。这些资源提供了应用运行…

EasyCVR告警类型设置后首页需要刷新才能更新的问题优化

EasyCVR视频融合平台基于云边端一体化架构&#xff0c;可支持多协议、多类型设备接入&#xff0c;包括&#xff1a;NVR、IPC、视频编码器、无人机、车载设备、智能手持终端、移动执法仪等。平台具有强大的数据接入、处理及分发能力&#xff0c;可在复杂的网络环境中&#xff0c…

Appium-Python-Client 源码剖析 (一) driver 的元素查找方法

目录 前言 源码版本:0.9 结构图&#xff1a; mobileby.py appium 的 webdriver.py selenium 的 webdriver.py seleniumdriver appiumdriver 前言 Appium-Python-Client是一个用于Python语言的Appium客户端库&#xff0c;它提供了丰富的API和功能&#xff0c;用于编写和…

cocosCreator 3.6以上接入腾迅Bugly 捕捉JS错误 Android

cocosCreator3.6以上接入Bugly上报其实很简单&#xff0c;不需要网上那么多弯弯绕&#xff0c;三须三步走。 1. 按照官网方式接入android的bugly 2. android端写一个Bugly上报管理类 3. 修改你工程目录下native\engine\common\Classes\目录下的Game.h, Game.cpp两个文件&…

字符串编程练习(C++)

ex1 字符串变形 描述 对于一个长度为 n 字符串&#xff0c;我们需要对它做一些变形。 首先这个字符串中包含着一些空格&#xff0c;就像"Hello World"一样&#xff0c;然后我们要做的是把这个字符串中由空格隔开的单词反序&#xff0c;同时反转每个字符的大小写。…

JS-27 前端数据请求方式;HTTP协议的解析;JavaScript XHR、Fetch的数据请求与响应函数;前端文件上传XHR、Fetch

目录 1_前端数据请求方式1.1_前后端分离的优势1.2_网页的渲染过程 – 服务器端渲染1.3_网页的渲染过程 – 前后端分离 2_HTTP协议的解析2.1_HTTP概念2.2_网页中资源的获取2.3_HTTP的组成2.4_HTTP的版本2.5_HTTP的请求方式2.6_HTTP Request Header2.7_HTTP Response响应状态码 3…

多媒体开发之cgo

go语言作为近十年来优秀的现代开发语言的代表&#xff0c;由于继承了c语言的简洁和很多现代语言的表达方式&#xff0c;在广泛的应用场景中得到众多爱好者的喜爱&#xff0c;如何将go和c、c进行联合开发&#xff0c;拓展整个开发生态&#xff0c;不用重复造轮子&#xff0c;掌握…

P1403 [AHOI2005] 约数研究

题目描述 科学家们在 Samuel 星球上的探险得到了丰富的能源储备&#xff0c;这使得空间站中大型计算机 Samuel II 的长时间运算成为了可能。由于在去年一年的辛苦工作取得了不错的成绩&#xff0c;小联被允许用 Samuel II 进行数学研究。 小联最近在研究和约数有关的问题&…