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

news2024/10/6 0:35:18

目录

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.coloradmin.cn/o/771912.html

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

相关文章

8年测试总结,App自动化测试-Appium常遇问题+解决(详细整理)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 问题1&#xff1a…

小白入门C#编写MVC登录小案例

一、C#编写MVC登录小案例 &#x1f680;1. 新建MVC项目。 &#x1f680;2. 在Models文件夹下创建一个User类&#xff0c;包含登录所需要的用户名和密码属性。 namespace MvcLogin.Models {public class User{public string UserName{get; set;}public string Password{get;se…

基于Java+SpringBoot+Vue+Uniapp前后端分离考试学习一体机设计与实现(视频讲解,已发布上线)

博主介绍&#xff1a;✌全网粉丝3W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

计算机基础专升本笔记三 计算机中的数据表示、编码

计算机基础专升本笔记三计算机中的数据表示、编码 一、计算机中的数据的单位 &#xff08;一&#xff09;数据存储的单位有哪些&#xff1f; 计算机存储单位有 bit, Byte, KB, MB, GB, TB, PB, EB, ZB, BB来表示。我们经常将Byte简称为B&#xff0c;将KB简称K。 &#xff08…

微信怎么自动加好友,通过好友后自动打招呼

很多客户朋友每天花大量的时间用手机搜索添加好友&#xff0c;这样的添加很集中也容易频繁&#xff0c;而且效率还低。对方通过后&#xff0c;有时也不能及时和客户搭建链接&#xff0c;导致客户也流失了。 现在可以实现自动添加和自动打招呼哦&#xff0c;只需要导入数据、设置…

linux查看ipynb文件

linux查看ipynb文件 使用jupyter查看 使用jupyter查看 安装 pip install jupyter添加配置好的环境到jupyter notebook的kernel中&#xff1a; python -m ipykernel install --user --name mmdet --display-name "mmdet"运行jupyter notebook &#xff08;在ipynb…

精选了6款好用的AI绘画工具,值得一试

近几年来&#xff0c;伴随着AI技术的发展&#xff0c;设计领域发生了巨大的变化。AI绘图工具的出现很大程度上减轻了设计师的工作负担&#xff0c;本文精选了6款优秀的AI绘图工具为大家推荐&#xff0c;一起来看看吧&#xff01; 1、即时灵感 即时灵感作为国产的AI绘图工具&a…

相机标定学习笔记

Kalibr 是标定工具中&#xff0c;唯一一个可以标定camToImu的&#xff0c;是vio必不可少的工具&#xff0c;其他的都有替代品。所以学习多种开源算法进行相机标定&#xff0c;并记录学习相机标定的过程。 一、相机标定 1、在场景中放置一个已知的物体 &#xff08;1&#xff…

ENSP实验四:搭建VPN(GRE,配置安全策略)

首先分析一下数据的流向&#xff1a; PC1->PC2 1、FW1&#xff1a;trust->dmz 【192.168.1.1->192.168.2.1 ICMP】 2、AR1->AR2&#xff1a;【202.1.1.1->202.1.3.1|GRE|192.168.1.1->192.168.2.1 icmp】 3、FW2&#xff1a; ①untrust->local …

提示工程师:如何写好Prompt

提示工程由来 提示工程是一门相对较新的学科&#xff0c;用于开发和优化提示以有效地将语言模型 (LM) 用于各种应用程序和研究主题。 研究人员使用提示工程来提高 LLM 在广泛的常见和复杂任务&#xff08;例如问题回答和算术推理&#xff09;上的能力。 开发人员使用提示工程…

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

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

用Vue如何实现低代码开发平台?

前言 在众多开发技术中&#xff0c;Vue组件化开发技术以其卓越的灵活性和高效性备受瞩目。 低代码平台相信不少人知道它的存在&#xff0c;而且现在大部分公司都在开发自己的低代码平台&#xff0c;首先我们来看看低代码平台可视化界面&#xff1a; 官网&#xff1a;https://ww…

UTM 4.3 发布:在 macOS 上优雅的使用 QEMU 虚拟化 Windows、Linux 和 macOS

UTM 4.3 发布&#xff1a;在 macOS 上优雅的使用 QEMU 虚拟化 Windows、Linux 和 macOS 在 iOS 中虚拟化 Windows、Linux 和 Unix 请访问原文链接&#xff1a;https://sysin.org/blog/utm-4/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xf…

Sql构建

Sql构建 SQL 构建对象介绍 之前通过注解开发时&#xff0c;相关 SQL 语句都是直接拼写的&#xff0c;一些关键字写起来比较麻烦、而且容易出错 MyBatis 提供了 org.apache.ibatis.jdbc.SQL 功能类&#xff0c;专门用于构建 SQL 语句 sql拼接测试&#xff1a; public class …

从制造到智造,安捷利的云数蝶变

伴随着新一轮科技革命和产业变革的兴起&#xff0c;制造业的数字化转型步入深水区&#xff0c;尤其是在5G、工业互联网、大数据等为代表的新技术推动下&#xff0c;制造业全方位、全链条的升级已是大势所趋。 南沙地处中国的南大门&#xff0c;既是国家面向世界的重要战略平台…

安达发|高级计划与智能排程APS软件的发展史进程

从泰勒的科学管理理论出发&#xff0c;率先追求科学的管理理论和管理工具&#xff0c;在计算机成为企业日常管理的基本工具之后&#xff0c;信息系统已经成为提高工厂管理水平的重要支柱。 在工厂计划领域&#xff0c;开始了从MRP到MRPII再到ERP的演变过程。MRPII指的是制造…

Appium+python自动化(十三)- 输入中文 - 一次填坑记(超详解)

简介 无论你在哪里&#xff0c;在做什么都会遇到很多坑&#xff0c;这些坑有些事别人挖的&#xff0c;有些是自己挖的。别人挖的叫坑人&#xff0c;自己挖的叫自杀&#xff0c;儿子挖的叫坑爹。因此在做app自动化道路上也不会是一帆风顺的&#xff0c;你会踩很多坑&#xff0c;…

异步fifo(1)

什么时异步fifo FIFO&#xff0c;即First In First Out &#xff0c;是一种先进先出的数据缓存器&#xff0c;异步FIFO 是指读写时钟不一致&#xff0c;读写时钟是互相独立的。数据从一个时钟域写入FIFO缓冲区&#xff0c;并从另一个时钟域的同一FIFO缓冲区中读取数据&#xf…

16. 存储过程和存储函数

文章目录 1.存储过程和存储函数2.创建和使用存储过程2.1 语法&#xff1a;2.2 第一个存储过程&#xff0c;打印hello world2.3 调用语法2.4 带参数的存储过程2.5 调试存储过程 3.创建和使用存储函数3.1 存储函数定义3.2 存储函数语法&#xff1a;3.3 存储函数案例&#xff1a; …

VR全景医疗:多渠道矩阵式使用,展现医疗实力

VR全景医疗的市场正在趋于成熟&#xff0c;医院将VR全景展示作为一种新颖的展示方式&#xff0c;在全景中嵌入官网&#xff0c;展现医院全貌&#xff0c;更可以凭借多渠道矩阵式使用&#xff0c;展现医疗实力&#xff0c;提高医院知名度。虽然这是一个全新的领域&#xff0c;但…