Linux 基本语句_7_C语言_文件I/O文件复制操作

news2024/9/28 15:22:56

标准I/O与文件I/O的区别:

在这里插入图片描述
标准I/O每次调用函数写入字符,并不是直接将字符写入文件,而是先写入缓冲区

文件I/O则是每次调用函数写入都会产生一次系统调用,Liunx必须从用户态切换至内核态,但过度频繁得执行系统调用会增加系统开销

标准I/O库通常更易于使用,因为它提供了更高级的函数,适用于许多不同的数据类型,文件I/O更接近底层,因此提供的控制更有限,通常需要更多的手动管理。

除此之外:

文件I/O相较于前者有着更小得内存开销,且更快,能对设备文件调用(linux一切皆是文件)而前者不行

文件I/O简介:

若说标准I/O的核心是流指针(FILE)那么文件I/O核心就是文件描述符

文件描述符:

文件描述符是一个非负整数,它是一个索引值,并指向在内核中每个进程代开文件的记录表。当打开一个或创建一个新文件时,内核就会向进程返回一个文件描述符,读写文件时需要把相应文件描述符作为参数传递给相应函数

进程:

听歌和打游戏就是两个不同进程,操作系统可以有效地管理这些不同的进程并分配资源。

I/O:

也通俗的讲就是你向计算机获取文件信息或向计算机写入信息。

在这里插入图片描述

通俗讲0、1、2描述符已被系统提前占据,后续打开新文件描述符的取值为3、4…

文件描述符作为有限资源,一个进程开启的最大文件描述符为1023,一个进程最多使用1024个文件描述符,这个值与文件,文件多少没有关系,已打开文件描述符个数有关

朴素的讲一个进程能同时打开的文件数量是有限的

操作:

打开文件:

在这里插入图片描述
open函数有俩重载函数,其中下面一个函数的mode是为型创建文件设置权限用的例如0777就是权限全开,第一个0没有用,后续文件权限可以用chmod对新建文件修改权限

在这里插入图片描述
这些权限可以叠加,用|即可:

在这里插入图片描述

标准I/O用的是fopen函数,返回值是FILE指针流

写文件:

在这里插入图片描述

ssize_t 是 C 和 C++ 编程语言中的一个数据类型,通常用于表示有符号的大小,主要用于 I/O 操作和函数返回值中。

在这里插入图片描述
read函数中count是期望读取的字节数,实际读取字只会小于等于count,读取数据存入buf中

void类型相当于java中的object

read函数的返还值,很特别后续有大用,后续代码测试中再细致说明

设置指针位置:

在这里插入图片描述
文件读取一般从文件开头开始读,读一字节再跳到下一字节,这个函数直接可以控制指针位置,可以控制读取文件的具体部分

关闭文件:

在这里插入图片描述
linux内核会自动关闭打开文件,为什么还要用close?

在Linux中,内核确实会在进程终止时自动关闭所有打开的文件。这是为了确保文件描述符不会被泄漏,从而释放与这些文件描述符相关的系统资源。

然而,显式地使用close函数来关闭文件是一种良好的编程习惯,而不是依赖于操作系统的自动处理。这是因为有时你可能需要在进程执行期间显式关闭文件,而不是等到进程终止。如果你在程序中打开了大量文件,如果不关闭它们,可能会导致文件描述符用尽,从而阻止进程打开更多文件。

另外,显式关闭文件可以帮助你更好地控制程序的文件访问,确保文件在不再需要时被及时释放,有助于避免资源泄漏问题。所以,尽管内核会在进程终止时关闭文件,但在实际编程中,最好养成显式关闭文件的好习惯。

使用文件I/O实现文件复制:

#include <stdio.h>                                                                                        
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#define N 10 //定义每次读取的长度

int main(int argc, const char * argv[]){
    int origin;//源文件
    int destination;//目的文件
    ssize_t readnum;
    unsigned char buf[N];
    if((origin = open(argv[1], O_RDONLY)) < 0){//打开源文件
       printf("源文件打开错误\n");
       exit(1);
    }
    if((destination = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0664)) > 0){//只写打开文件,不存在创建,否者清空
      lseek(destination, 0, SEEK_SET);//将指针制于文件首部
      
      while((readnum = read(origin, buf, N)) > 0){//若读取出数据
           write(destination, buf, N);//写入
      }
    }else{
       printf("目标文件打开错误\n");
       exit(1);
    }
    return 0;
}

效果:

./a.out main.c ccc.c

复制main.c到ccc.c文件可以看出:
在这里插入图片描述
ccc.c文件多出来一个trun 0

在这里插入图片描述

这个原因的产生和我们的写函数脱不了关系

 if((destination = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0664)) > 0){
   lseek(destination, 0, SEEK_SET);//将指针制于文件首部

   while((readnum = read(origin, buf, N)) > 0){//若读取出数据
        write(destination, buf, N);//写入
   }
 }else{
    printf("目标文件打开错误\n");                                      
    exit(1);
 }

write(destination, buf, N);//写入

问题出在写入函数写入的实际长度为N,若read函数没有读取到长度为N的字符串,那么write写入的时候剩下就就会补0这也就是turn 0产生的原因

while((readnum = read(origin, buf, N)) > 0)

改进方法,讲N换成read函数的返回值即可,read在读取到一些字符串,并且刚好到达文件末尾仍会返回读取的字符串个数,而不是0,但当你再次调用想获取更多字符串的时候就会返回0

修改代码:

#include <stdio.h>                                                                                        
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#define N 10 //定义每次读取的长度

int main(int argc, const char * argv[]){
    int origin;//源文件
    int destination;//目的文件
    ssize_t readnum;
    unsigned char buf[N];
    if((origin = open(argv[1], O_RDONLY)) < 0){//打开源文件
       printf("源文件打开错误\n");
       exit(1);
    }
    if((destination = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0664)) > 0){//只写打开文件,不存在创建,否者清空
      lseek(destination, 0, SEEK_SET);//将指针制于文件首部
      
      while((readnum = read(origin, buf, N)) > 0){//若读取出数据
           write(destination, buf, readnum);//写入
      }
    }else{
       printf("目标文件打开错误\n");
       exit(1);
    }
    return 0;
}

效果:
在这里插入图片描述

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

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

相关文章

Btrace入门

一、前言 今天收到客户报的一个Bug,登录系统查看发现没有相关日志输出&#xff0c;方法中相关的请求参数及变量都没有打印出来&#xff0c;给排查问题造成很大不便&#xff0c;我们知道解决Java系统疑难杂症有两大利器&#xff0c;其一是tcpdump用于网络抓包分析 、其二是Btra…

智能水厂运行与调控3D模拟仿真在线展示提高整个系统的协同效应

水厂在生活中的重要性不可忽视。它们提供清洁、安全的水源&#xff0c;满足人们饮用、洗浴、烹饪等基本需求&#xff0c;保障公共卫生&#xff0c;预防疾病传播;同时&#xff0c;水厂也促进经济发展&#xff0c;为工业生产和农业灌溉提供保障&#xff0c;吸引和支持企业的投资和…

你的Jmeter是不是经常乱码?教你用四种方法解决它!

乱码的原因&#xff1a; 一般情况下jemeter默认设置的编码格式为&#xff1a;ISO-8859-1&#xff0c;而我们程序中经常使用的是UTF-8编码&#xff0c;由于响应页面和jmeter编码格式不统一导致响应结果中经常会乱码&#xff0c;所以需要将jmeter的编码格式设置为UTF-8来解决乱码…

ardupilot开发 --- EKF 篇

1. EKF1~EKF3 待续… 2. Ardupilot滤波算法的演变 使用DCM还是EKF? AHRS_EKF_USE: set to “1” to use the EKF, “0” to use DCM for attitude control and inertial nav (Copter-3.2.1) or ahrs dead reckoning (Plane) for position control. In Copter-3.3 (and highe…

day15_集合

今日内容 1.复习 2.LinkedList 3.Set(HashSet、TreeSet) 4.Map(HashMap) 一、复习 List集合的特点? 有序,允许重复 ArrayList的底层实现原理,以及特点 数组,初始10,扩容1.5倍查询更新快,删插入慢解释为什么快,慢? 增强for循环语法 写出以下几个集合的方法签名 向集合添加元素…

Unity URP14.0 自定义后处理框架

目录 碎碎念一些基础CustomPostProcessing.csCustomPostProcessingFeature.csCustomPostProcessingPass.cs例子&#xff1a;BSC后处理shader&#xff08;BSC&#xff09;后处理cs脚本(BSC) 例子&#xff1a;ColorBlitPostProcessing.hlslColorBlit2.shaderColorBlit.cs文件 其他…

快捷键记录

文章目录 ctrlaltashftwinsWinRCtrlc和CtrlvCtrl -Xshell的复制粘贴ctrlalt&#xff08;鼠标跳出&#xff09;ctrl alt T ctrlalta 这是QQ/TIM的屏幕截图快捷键。截图成功后&#xff0c;会有一栏导航&#xff0c;可以对图片进行勾画、模糊、绘画、标号、撤回、翻译、提取文…

早停止(Early Stopping)-PyTorch版本(代码使用教程)

一、说明 记录自己使用早停法来解决过拟合问题的经历。 这里给出的是pytorch版本&#xff0c;需要tensorflow版本的&#xff0c;可以使用chatgpt转换&#xff0c;也可以自己转换。 二、原理 这个早停法的原理就是&#xff0c;对比你每次的验证loss&#xff0c;如果超过20epoch&…

AQS总结

详细分析地址&#xff1a;跳转 head等于NodeA&#xff0c;NodeA指向NodeB&#xff0c;NodeB指向NodeC&#xff0c; tail等于NodeC。 NodeA也就是持有线程的Node&#xff0c;阻塞队列是指NodeA后面的所有队列&#xff0c;NodeA不属于阻塞队列。 公平锁&#xff1a; A线程先进来…

广西厂家直销建筑模板,工程用木工板,多层胶合板批发

欢迎选购我们的产品&#xff1a;广西厂家直销的建筑模板。作为一家专业厂家&#xff0c;我们提供工程用木工板&#xff0c;采用标准尺寸的多层胶合板制作&#xff0c;具备出色的防潮耐磨性能和高周转次数。 1. 工程用途&#xff1a;我们的建筑模板专为各类工程使用而设计&#…

(echarts)雷达图封装相关总结及使用

(echarts)雷达图封装相关总结及使用 数据结构&#xff1a; 页面&#xff1a; <div id"chart4" style"height:420px;width: 100%;" />//雷达图 echartFour(obj) {var chartDom document.getElementById("chart4");var myChart echarts.i…

浙大做了一个可用于AI领域的学术会议问答LLMs

深度学习自然语言处理 原创作者&#xff1a;wkk 今天介绍一篇来自于浙江大学的一项研究&#xff0c;关于基于LLM进行人工智能领域内7个不同学术会议QA数据集的论文。 论文: Reliable Academic Conference Question Answering: A Study Based on Large Language Model地址: http…

网络攻击的发展

在当今数字化时代&#xff0c;网站被攻击已经成为常态&#xff0c;网络威胁愈演愈烈。这些攻击不仅威胁到企业的安全&#xff0c;还可能导致严重的商业危机。本文将探讨为什么网络流量攻击变得如此普遍和容易&#xff0c;并分析未来可能引发的商业危机。 ​ 网络流量攻击的普遍…

【博士每天一篇文献-算法】iCaRL_ Incremental Classifier and Representation Learning

阅读时间&#xff1a;2023-10-27 1 介绍 年份&#xff1a;2017 作者&#xff1a;Sylvestre-Alvise Rebuffi; Alexander Kolesnikov; Georg Sperl; Christoph H. Lampert &#xff0c;牛津大学 期刊&#xff1a;Proceedings of the IEEE conference on Computer Vision and Pa…

竞赛选题 深度学习图像修复算法 - opencv python 机器视觉

文章目录 0 前言2 什么是图像内容填充修复3 原理分析3.1 第一步&#xff1a;将图像理解为一个概率分布的样本3.2 补全图像 3.3 快速生成假图像3.4 生成对抗网络(Generative Adversarial Net, GAN) 的架构3.5 使用G(z)生成伪图像 4 在Tensorflow上构建DCGANs最后 0 前言 &#…

评比无代码低代码平台时,可以考虑以下几个方面

无代码低代码平台是近年来兴起的一种软件开发工具&#xff0c;它们旨在帮助非技术人员快速创建应用程序&#xff0c;而无需编写大量的代码。这些平台通过提供可视化的界面和预先构建的组件&#xff0c;使用户能够通过拖放和配置的方式来构建应用程序。选择无代码低代码平台时&a…

微信公众号点击打开地图导航

<h3 id"menu-location">地理位置接口</h3><span class"desc">使用微信内置地图查看位置接口</span><button class"btn btn_primary" id"openLocation">openLocation</button> <span class&quo…

发展高质量存储力,中国高科技力量聚浪成潮

中国信息通信研究院指出&#xff0c;在全球数字化转型与产业变革的浪潮下&#xff0c;算力正在成为改变全球竞争格局的关键力量。而根据最新的《算力基础设施高质量发展行动计划》&#xff0c;算力是集信息计算力、数据存储力和网络运载力于一体的新型生产力。当前&#xff0c;…

ORACLE-递归查询、树操作

1. 数据准备 -- 测试数据准备 DROP TABLE untifa_test;CREATE TABLE untifa_test(child_id NUMBER(10) NOT NULL, --子idtitle VARCHAR2(50), --标题relation_type VARCHAR(10) --关系,parent_id NUMBER(10) --父id );insert into untifa_test (CHILD_ID, TITLE, RELATION_TYP…