Linux-cp命令实现-系统调用和函数区别-文件截断-文件空洞

news2024/11/25 16:36:52

1、实现CP命令

        vimdiff  file1  file2      vimdiff是Vim编辑器的一个功能,主要用于比较两个或多个文件之间的差异,并在一个Vim窗口中显示这些差异。这个功能特别适合用于比较修改前后的文件,或者比较两个不同版本的文件。

        注意:用read的返回值判断要写的数据长度和停止读写的条件

cp功能实现

#include<43func.h>
int main(int argc,char *argv[]){
    //cp src dest
    ARGS_CHECK(argc,3);
    int fdr = open(argv[1],O_RDONLY);
    ERROR_CHECK(fdr,-1,"open fdr");
    int fdw = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0666);
    ERROR_CHECK(fdw,-1,"open fdw");
    char buf[4096] = {0};
    while(1){
        memset(buf,0,sizeof(buf));
        ssize_t ret = read(fdr,buf,sizeof(buf));
        if (ret == 0)
        {
            break;
        }
        write(fdw,buf,ret);//ret表示读多少写多少;
    }
    close(fdr);
    close(fdw);
}

        

一个程序读取,一个程序写,用管道连接就可以实现远程拷贝。

性能问题(代码优化)

充分利用缓冲系统来减少指令预测。


系统调用和普通函数的区别:

上下文切换:系统调用:涉及从用户模式切换到内核模式,这需要进行上下文切换。上下文切换的过程包括保存当前用户进程的上下文环境,切换到内核模式,执行系统调用处理函数,然后恢复用户进程的上下文环境。由于上下文切换的开销,系统调用的执行通常比函数调用更加耗时。普通函数:只涉及在程序内部的代码跳转,不需要上下文切换。因此,函数调用的执行速度更快。

功能和权限:系统调用:提供了对操作系统功能和资源的访问权限。它们可以执行特权操作,例如文件系统操作、进程管理、网络通信等。由于系统调用运行在内核模式下,它们可以执行更底层的操作,但同时也受到操作系统的限制。普通函数:只能执行定义在程序中的功能代码。它们没有直接的访问操作系统底层功能的权限,只能通过系统调用间接访问。

调用方式:系统调用:通过软中断或陷阱指令触发。当应用程序需要执行特权操作时,它会使用特定的系统调用号调用对应的系统调用函数。普通函数:通过在程序中调用函数的名称来触发。函数可以是程序内部定义的,也可以是外部库提供的。

作用范围:系统调用:是用户进程与操作系统内核交互的接口,用于请求操作系统内核提供的服务和资源。普通函数:在程序内部定义和使用,用于封装和复用特定的功能代码。

安全性和稳定性:系统调用:由于涉及到操作系统内核和底层资源的访问,系统调用在设计和实现时需要特别考虑安全性和稳定性。不当的系统调用可能导致系统崩溃或数据损坏。普通函数:主要关注功能的正确性和效率,安全性和稳定性的要求相对较低。


用户态使用系统调用时,会陷入到内核态,进入内核态和进入用户态都要消耗时间。

当用户态缓冲区较大时,需要切换用户态和内核态的次数就会变少,节省了时间。

buf越大越好(减少状态切换的次数)。4096字节。

fopen,fread,fwrite, 作为c的库函数,但是要用到用户态缓冲,也会创建文件对象,在内核态中。

fopen在内核中创建了文件对象,在用户态中有一个文件流,所以该函数的buf会写入缓冲(缓冲是在用户态中的文件流实现的),

缓冲的类型:
  1. 全缓冲(Full Buffering)
    • 定义:当填满标准I/O缓存后才进行实际的I/O操作。
    • 典型代表:对磁盘文件的读写操作通常使用全缓冲。
    • 刷新时机:缓冲区满时、执行flush语句、执行endl语句或关闭文件时,会刷新缓冲区进行真正的I/O操作。
  2. 行缓冲(Line Buffering)
    • 定义:在输入和输出中遇到换行符时,执行真正的I/O操作。
    • 典型代表:键盘输入数据通常采用行缓冲,即输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。
    • 刷新时机:与全缓冲类似,但主要区别在于刷新时机是遇到换行符时。
  3. 不带缓冲(No Buffering)
    • 定义:不进行缓冲,数据直接进行I/O操作。
    • 典型代表:标准出错情况stderr是典型的不带缓冲输出,这使得出错信息可以直接尽快地显示出来。
    • 刷新时机:由于不进行缓冲,所以没有特定的刷新时机。

当buf给file缓冲区传输数据时,一般等缓冲区满了才会传输数据到用户态的文件流

使用用户态的fopen,fread,fwrite,

优势:(零碎写入读写文件使用文件流时,可以最大程度上保证用户态和内核态切换次数处于比较少的情况。

通过缓冲区,可以将多次小型的读写操作合并成一次较大的操作,从而提高了磁盘I/O的效率)

劣势:(拷贝次数更多。当数据从磁盘读入到用户态的缓冲区时,或者从用户态的缓冲区写入到磁盘时,都会发生内存拷贝。这些拷贝操作会增加CPU的开销。

在用户态和内核态之间维护缓存可能会导致缓存一致性问题。如果内核态的缓冲区或磁盘上的数据被其他进程或系统调用修改,而用户态的缓冲区没有及时更新,就可能导致数据不一致。

文件流缓冲区的管理(如分配、释放、刷新等)需要额外的代码和逻辑来处理,这增加了编程的复杂性。)


文件截断:ftruncate(按字节截断文件)可以用于创建一个固定大小的文件。

#include <43func.h>
int main(int argc ,char *argv[]){
    ARGS_CHECK(argc,2);
    int fd = open(argv[1],O_RDWR);
    ERROR_CHECK(fd,-1,"open");
    int ret = ftruncate(fd,20);
    ERROR_CHECK(ret,-1,"ftruncate");
}

大文件截断成小文件就直接去掉,小文件截断成大文件直接补0.二进制0.。截断是直接影响文件大小。

stat命令在Linux系统中用于显示文件或文件系统的状态信息

用该系统调用截断成40960大小。

8个BLOCK,一个block假设为512byte,实际上给了4096空间,但具体大小只有414byte。所以形成文件空洞。

文件总大小为40960,4096分配了磁盘。

操作系统不会给空出来的区域分配磁盘,可以把空出来的区域叫做文件空洞。

文件空洞的概念

定义
在UNIX文件系统中,文件位移量(offset)可以大于文件的当前长度。当对这样的文件进行写操作时,文件会被“撑大”,并在文件中构成一个空洞(hole)。空洞是文件中没有实际写入数据的部分,由重复的0表示。

特点

  1. 不占用磁盘空间:在写入数据之前,空洞并不占据磁盘空间。文件系统会将其解释为0的子串,并将对应链表的指针设为空。
  2. 预留磁盘空间:虽然空洞本身不占用磁盘空间,但文件系统会扣减程序可用的磁盘空间数值大小,以实现预留。
  3. 读写行为:使用read函数读取空洞部分时,返回的数据是0。使用cp命令拷贝的文件,空洞部分不会被拷贝,因此生成的同样文件占用磁盘空间较小。

使用场景

1. 下载数据

  • 迅雷下载:在下载过程中,迅雷会先创建一个与最终文件大小相同的空洞文件,以便在多线程下载时从不同的地址写入数据。这样可以确保即使磁盘空间被其他程序占用,下载也不会因磁盘空间不足而中断。
  • 预留磁盘空间:在下载大文件时,利用文件空洞可以确保磁盘空间被预留,从而避免下载过程中因磁盘空间不足而中断。

2. 数据库文件

  • 压缩和优化:数据库文件通常包含大量空洞。通过使用文件空洞填充技术,可以压缩数据库文件的大小,提高存储效率和读写性能。

3. 网络开发

  • 优化传输:在网络传输中,文件空洞填充技术可以用于压缩网络数据包的大小,减少数据传输的时间和带宽占用。例如,在文件传输协议中,可以将逻辑上的空洞视为本地主机上的零字节,以减少传输数据量。

4. 虚拟机存储

  • 优化存储:在虚拟机环境中,文件空洞填充可以用于优化虚拟机磁盘的存储空间,提高存储效率。

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

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

相关文章

SD卡无法读取:原因解析与数据恢复策略

一、SD卡无法读取的尴尬场景 在数字化日益普及的今天&#xff0c;SD卡作为便携式存储设备&#xff0c;广泛应用于各类电子设备中。然而&#xff0c;当您急需访问SD卡中的数据时&#xff0c;却发现设备无法读取SD卡&#xff0c;这无疑是一个令人沮丧的场景。SD卡无法读取可能表…

【已解决】在IDEA中使用Git拉取代码时提示:Can‘t update / master has no tracked branch

文章目录 问题描述原因分析解决方案 问题描述 在IDEA中使用Git拉取代码&#xff0c;尝试更新本地项目代码&#xff0c;提示 " Cant update / master has no tracked branch "&#xff0c;如下图所示&#xff1a; 原因分析 出现上述问题意味着本地名为master的分支&…

Google Earth Engine(GEE)——ui.DateSlider时间进度条的设置

结果 函数: ui.DateSlider(start, end, value, period, <

排序不等式——AcWing 913. 排队打水

排序不等式 定义 这主要涉及到利用 C 的排序操作对数据进行排序后&#xff0c;基于排序结果进行一些分析和处理。 运用情况 对一组数据进行排序后&#xff0c;根据排序后的顺序来解决一些与顺序相关的问题&#xff0c;比如选取最大或最小的若干个元素。在一些需要按照特定顺…

前端项目结构介绍与Vue-cli(脚手架)环境搭建

传统的前端项目结构 一个项目中有许多html文件 每一个html文件都是相互独立的 如果需要在页面中导入一些外部依赖的组件(vue.js,elementUI),就需要在每一个html文件中引用都导入,十分的麻烦 而且这些外部组件都需要在其官网中自行下载,也增加了导入的繁琐程度 当今的前端项…

NeRF从入门到放弃5: Neurad代码实现细节

Talk is cheap, show me the code。 CNN Decoder 如patch设置为32x32,patch_scale设置为3&#xff0c;则先在原图上采样96x96大小的像素块&#xff0c;然后每隔三个取一个像素&#xff0c;降采样成32x32的块。 用这32x32个像素render feature&#xff0c;再经过CNN反卷积预测…

【C语言】关于字符串函数的使用及模拟实现(1)

一、字符串追加 1.1 库函数srecat的使用 1.2 库函数strncat的使用 1.3 模拟实现库函数 strcat 及 strncat 由上可知&#xff0c;字符串追加的原理是找到所添加字符串的 \0 位置&#xff0c;再对其进行添加。 代码1、 代码2、 二、字符串查找 2.1 库函数strstr的使用 使用…

Android应用保活实践

} override fun onBind(intent: Intent): IBinder? { return mBilder } override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { //播放无声音乐 if (mediaPlayer null) { mediaPlayer MediaPlayer.create(this, R.raw.novioce) //声音设置为0 me…

如何打造稳定、好用的 Android LayoutInspector?

速度极慢&#xff0c;遇到复杂的布局经常超时 某些情况无法选中指定的 View 本文将围绕 LayoutInspector 的痛点&#xff0c;分析问题并修复&#xff0c;最终将 LayoutInspector 变成一个稳定、好用的插件。 二、加速 Dump View Hierarchy 2.1 问题描述 开发复杂业务的同学…

JavaWeb——MySQL:DDL操作库

目录 1.DDL&#xff1a;查询数据库&#xff1b; 1.1 查询数据库 1.2 创建数据库 1.DDL&#xff1a;查询数据库&#xff1b; 具体操作&#xff1a;增 删 查 用 &#xff1b; 1.1 查询数据库 SQL语句&#xff1a;show databases; 由于我创建过一些数据库&#xff0c;我查询的…

windows无法启动redis-server

Warning: no config file specified, using the default config. In order to specify a config file use D:\Code_enve\Redis\redis-server.exe /path/to/redis.conf Creating Server TCP listening socket *:6379: bind: No such file or directory以上是问题的报错信息&…

做Android开发怎么才能不被淘汰?

多学一项技能&#xff0c;可能就会成为你升职加薪的利器。经常混迹于各复杂业务线的人&#xff0c;才能跳出重复工作、不断踩坑的怪圈。而一个成熟的码农在于技术过关后&#xff0c;更突出其他技能对专业技术的附加值。 毋须讳言的是&#xff0c;35岁以后你的一线coding能力一…

Tableau数据可视化与仪表盘搭建

Tableau的主要目的 数据赋能和数据探索。 数据赋能&#xff1a; 1.分析师可以将数据看板发布到线上给其他部门使用 2.自动更新看板 3.自由下载数据 4.线上修改图表 5.邮件发送数据 6.设置数据预警 数据探索&#xff1a; 1.支持亿级数据的连接和处理 2.自由地对字段进行各种…

【鸿蒙 HarmonyOS】尺寸设置:size/layoutWeight/constraintSize

一、背景 常见尺寸&#xff1a;width&#xff08;宽度&#xff09;、height&#xff08;高度&#xff09;、padding&#xff08;内边距&#xff09;、margin&#xff08;外边距&#xff09; 主要整理下size&#xff08;设置高宽尺寸&#xff09;、layoutWeight&#xff08;对…

Go 三色标记法:一种高效的垃圾回收策略

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

【秋招刷题打卡】Day02-二分系列之-二分查找

Day02-二分系列之-二分查找 前言 给大家推荐一下咱们的 陪伴打卡小屋 知识星球啦&#xff0c;详细介绍 >笔试刷题陪伴小屋-打卡赢价值丰厚奖励 < ⏰小屋将在每日上午发放打卡题目&#xff0c;包括&#xff1a; 一道该算法的模版题 (主要以力扣&#xff0c;牛客&#…

chrome 使用本地替换功能替换接口返回内容

前言 在web开发或测试过程中&#xff0c;我们经常会需要修改接口返回值来模拟数据进行开发或测试。 常用的方式一般通过抓包工具&#xff0c;如charles&#xff0c;或fildder 的功能。 例如我们可以使用charles打断点的方式&#xff0c;或者使用charles的map local 功能进行…

Python18 数据结构与数据类型转换

1.python中的数据结构 在Python中&#xff0c;数据结构是用来存储、组织和管理数据的方式&#xff0c;以便有效地执行各种数据操作。Python提供了几种内置的数据结构&#xff0c;每种都有其特定的用途和操作方法。以下是Python中一些主要的数据结构&#xff1a; 1.列表&#…

【大数据】—量化交易实战案例(基础策略)

声明&#xff1a;股市有风险&#xff0c;投资需谨慎&#xff01;本人没有系统学过金融知识&#xff0c;对股票有敬畏之心没有踏入其大门&#xff0c;所以只能写本文来模拟炒股。 量化交易&#xff0c;也被称为算法交易&#xff0c;是一种使用数学模型和计算机算法来分析市场数…

网络程序通信的流程

网络程序通信的流程&#xff1a; 1.通过ip地址找到网络中的设备 2.通过端口号找到对应进程的端口 3.传输数据时还需要使用传输协议&#xff08;TCP&#xff09;&#xff0c;保证数据的可靠性 4.socket完成进程之间网络数据的传输 ip地址的介绍 IP地址是互联网协议地址&#…