Linux中对文件的操作(二)

文件描述符

文件描述符fd是通过open打开某一文件后返回的非负整数。在Linux系统中默认存在的文件描述符有0——标准输入,1——标准输出,2——标准错误

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main(){int fd;char readBuf[128];int n_read = read(0,readBuf,5);int n_write = write(1,readBuf,strlen(readBuf));printf("\ndone!\n");return 0;
}

上述代码的作用就是使用read基于标准输入通过键盘读取5个字符,之后使用write基于标准输出读取5个字符。
文件描述符只针对当前进程。

在linux中对文件操作需要注意的点

  1. 在linux中药操作一个文件,一般是先open打开一个文件,得到文件描述符,然后对文件进行读写操作(或其他操作),最后是close关闭文件即可。
  2. 对文件操作时一定要先打开文件,打开成功之后次啊能操作,如果打开失败,就不用进行后边的操作了,最后读写完成后一定要关闭文件,否则会造成文件损坏。
  3. 文件平时是存放在块设备(磁盘)中的文件系统文件中的,我们把这种文件叫静态文件,当我们去open打开一个文件时,linux内核做的操作包括:内核在进程中建立一个打开文件的数据结构(结构体),记录下我们打开的这个文件;内核在内存中申请一段内存,并且将静态文件的内容从块设备中读取到内核中特定地址管理存在(叫动态文件)
  4. 打开文件以后,以后对这个文件的读写操作,都是针对内存中的这一份动态文件的,而不是针对静态文件的。当然我们对动态文件进行读写以后,此时内存中动态文件和块设备文件中的静态文件就不同步了,当我们close关闭动态文件时,close内部内核将内存中的动态文件的内容去更新(同步)块设备中的静态文件。
  5. 为什么这么涉及,不直接对块设备进行操作?
    块设备本身读写非常不灵活,是按块读写的,而内存是按字节单位操作的,而且可以随机操作,很灵活。

实现linux cp命令的代码

cp src.c des.c
思路:
首先要对参数进行拆解
1.打开src.c
2.读src中的内容到buf
3.打开/创建des.c
4.将buf写入到des.c
5.close两个文件

参数拆解

因为我们需要打开源文件和目标文件,因此需要对cp src.c des.c进行参数拆解。代码如下:

#include <stdio.h>int main(int argc,char** argv)
{printf("total params:%d\n",argc);printf("No.1 params:%s\n",argv[0]);printf("No.2 params:%s\n",argv[1]);printf("No.3 params:%s\n",argv[2]);return 0;
}

此时需要补全main函数的参数argc和argv;

代码实现cp命令


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main(int argc,char** argv){int fdSrc,fdDes;char *readBuf=NULL;if(argc != 3){	//参数个数不为3时直接报错退出printf("params error\n");exit(-1);}fdSrc = open(argv[1],O_RDWR);	//打开源文件int size = lseek(fdSrc,0,SEEK_END);	//计算源文件大小lseek(fdSrc,0,SEEK_SET);        //将光标恢复到头readBuf = (char *)malloc(sizeof(char)*size+8);	//开辟空间int n_read = read(fdSrc,readBuf,size);	//从源文件中读取数据fdDes = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);	//打开目标文件,如果不存在就creat,如果已经存在了,就会根据O_TRUNC清空之前的数据。int n_write = write(fdDes,readBuf,strlen(readBuf));	//写入数据close(fdSrc);	//关闭文件,不要忘记了!close(fdDes);return 0;
}

运行代码gcc test4.c -o mycp
./mycp test4.c new.c
就可以实现对test4.c进行复制的操作

文件编程 修改配置文件

思路:
1.找到需要修改那一行的位置a
2.a往后移动到我们需要修改的参数之前的位置b
3.修改b位置的参数

可以利用strstr函数来找到a位置
**char *strstr(const char haystack, const char needle);
RETURN VALUE
These functions return a pointer to the beginning of the substring, or NULL if the substring
is not found.返回子串的起始位置。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main(int argc,char** argv){int fdSrc;char *readBuf=NULL;if(argc != 2){printf("params error\n");exit(-1);}fdSrc = open(argv[1],O_RDWR);int size = lseek(fdSrc,0,SEEK_END);lseek(fdSrc,0,SEEK_SET);        //将光标恢复到头readBuf = (char *)malloc(sizeof(char)*size+8);int n_read = read(fdSrc,readBuf,size);char *p = strstr(readBuf,"LENG=");if(p == NULL){printf("not found\n");exit(-1);}else{printf("change success\n");}p=p+strlen("LENG=");*p = '5';	//考虑如果我们写入的是整型数5,会是什么情况lseek(fdSrc,0,SEEK_SET);int n_write = write(fdSrc,readBuf,strlen(readBuf));close(fdSrc);return 0;
}

原先的数据是:
SPEED=3
LENG=3
SCORE=9
LEVEL=5
修改后的数据为:
SPEED=3
LENG=5
SCORE=9
LEVEL=5

修改配置文件时,写入一个整数

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main(){int fd;int data1 = 10;int data2 = 0;fd = open("./file1",O_RDWR);int n_write = write(fd,&data1,sizeof(int));lseek(fd,0,SEEK_SET);	//使光标回到头int n_read = read(fd,&data2,sizeof(int));printf("read:%d\n",data2);	//输出read:10close(fd);return 0;
}

写入一个结构体


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>struct Test{int a;char c;
};int main(){int fd;struct Test data1 = {10,'a'};struct Test data2;fd = open("./file1",O_RDWR);int n_write = write(fd,&data1,sizeof(struct Test));lseek(fd,0,SEEK_SET);int n_read = read(fd,&data2,sizeof(struct Test));printf("read:%d %c\n",data2.a,data2.c);close(fd);return 0;
}

总结:

不要陷入思维定势!!
*ssize_t write(int fd, const void buf, size_t count);
*ssize_t read(int fd, void buf, size_t count);
write和read的第二个参数,不一定非得是一个字符数组,只要求是一个指针即可,指针的本质就是地址,因此传入一个地址也是可以的,就像上面的两块代码一样,传入&data1也是可以的!

了解fopen和open的区别

  1. 来源:****open是UNIX系统调用函数(包括LINUX),返回的是文件描述符fd,它是文件在文件描述符表里的索引。fopen是标准C语言库函数,在不同的系统中应该调用不同的内核api。返回的是一个指向文件结构的指针。
    2.移植性fopen是C标准函数,因此有良好的移植性;而open是UNIX系统调用,移植性有限。如windows下相似的功能使用API函数‘CreateFile’。
  2. 适用范围open的适用范围比fopen大,fopen适用于操纵普通正规文件,而UNIX下的一切设备都是以文件的形式操作,如网络套接字、硬件设备等。
  3. 文件IO层次open属于低级IO函数,fopen属于高级IO函数。低级和高级的简单区分标准是:谁离内核更近。低级文件IO运行在内核态,高级文件IO运行在用户态。
    5.缓冲fopen都在缓冲区中进行操作,操作外存的次数少,执行速度快,效率高;open需要在用户态和内核态之间切换,效率相对较低

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

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

相关文章

如何构建用于从收据中提取信息的生成式人工智能工具

原文地址&#xff1a;how-to-build-a-generative-ai-tool-for-information-extraction-from-receipts 使用 LangChain 和 OpenAI 工具从 Google Drive 中存储的收据图像中提取结构化信息 2024 年 4 月 10 日 纸质收据有各种样式和格式&#xff0c;是自动信息提取的一个有趣目…

Web服务器手动配置

目录 配置环境 http配置 配置步骤 1、首先安装Nginx&#xff08;已经安装的跳过这步&#xff09; 2、查看一下下Nginx的配置文件结构&#xff0c;了解如何配置&#xff0c;以及配置的各个条目有什么作用&#xff08;为接下来的配置打基础&#xff09; 3、创建你的网页 4、…

【JAVA项目】基于ssm的协同过滤算法的【图书推荐系统】

技术简介&#xff1a;采用B/S架构、ssm 框架、Java技术、MySQL等技术实现。 系统简介&#xff1a;系统权限按管理员和用户这两类涉及用户划分。&#xff08;1&#xff09;管理员功能需求 管理员登陆后&#xff0c;主要包括首页、个人中心、用户管理、书籍管理、书籍分类管理、热…

牛客NC382 切割木头【中等 二分超找 Java/Go/C++】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/707d98cee255448c838c76918a702be0 核心 二分查找Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可…

安卓 app icon大小 安卓app界面尺寸大小

移动应用的界面设计画布尺寸设计多大&#xff08;特别是Android&#xff09;、图标和字体大小怎么定、需要设计多套设计稿么、如何切图以配合开发的实现&#xff1f; 本篇将结合iOS和android官方的设计规范、搜集的资料以及工作中的摸索&#xff0c;来分享移动应用界面设计中的…

gcc编译器分析

gcc编译器分析 参考词法分析语法分析预读一个符号语法分析函数调用关系重点函数分析c_parse_filec_parser_translation_unit 参考 《gcc源码分析》 词法分析 词法分析的过程就是将源代码识别成一个一个的词法符号&#xff0c;并在词法分析的过程中创建一些树节点&#xff0c…

tomcat+nginx 动静分离

一、单机反向代理 7-1 7-2 测试 二、多机反向代理 1. 环境准备 机器IP地址服务7-1172.168.1.11nginx7-2172.168.1.12tomcat7-3172.168.1.13tomcat 2. 配置7-1 Nginx 服务器 vim /apps/nginx/conf/nginx.confhttp:upstream tomcat {server 172.168.1.12:8080;server …

探索设计模式的魅力:分布式模式让业务更高效、更安全、更稳定

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 ✨欢迎加入探索分布式模式之旅✨ 在数字化时代&#xff0c;企业面临着前所未有的挑战和机遇。…

STM32开发笔记-新建标准库工程

1.STM32开发方式 STM32开发一般包括三种方式&#xff1a;基于寄存器开发、基于标准外设库开发、基于HAL库开发。 标准外设库是最基础的STM32开发方式&#xff0c;提供了一系列函数用于配置和控制STM32的外设&#xff0c;如GPIO、USART、SPI等。使用标准外设库需要手动编写代码…

(39)4.29数据结构(栈,队列和数组)栈

#include<stdlib.h> #include<stdio.h> #define MaxSize 10 #define Elemtype int 1.栈的基本概念 2.栈的基本操作 typedef struct { Elemtype data[MaxSize]; int top; }Sqstack;//初始化栈 void InitStack(Sqstack& S) { S.top -1; //初始化…

Golang日志管理:使用log/slog实现高级功能和性能优化

Golang日志管理&#xff1a;使用log/slog实现高级功能和性能优化 简介基础使用初始化和配置日志级别 高级技巧自定义日志格式器条件日志处理 实战案例场景一&#xff1a;API请求日志记录场景二&#xff1a;错误跟踪和用户通知 性能优化优化日志记录的性能异步日志处理选择合适的…

Vue的项目启动指令分析

通过Vue CLI脚手架创建的项目&#xff0c;默认的启动项目方式是 npm run serve 这里的serve是可以修改的。 在创建的项目目录中&#xff0c;找到package.json 双击打开&#xff0c;找到scripts部分 在scripts部分&#xff0c;有一个"serve"键值对&#xff0c;这里的…

机器学习-K近邻算法(KNN)

目录 什么是KNN算法 图解KNN基本算法 &#xff08;1&#xff09;k近邻算法中k的选取 &#xff08;2&#xff09;距离函数 &#xff08;3&#xff09;归一化处理 &#xff08;4&#xff09;概率kNN KNN算法的优缺点 优势 缺点 KNN算法总结 什么是KNN算法 k近邻算法&…

[Spring Cloud] (6)gateway整体加解密

文章目录 简述整体效果后端增加配置nacos增加配置GlobalConfig 添加请求整体解密拦截器DecryptionFilter添加响应整体解密拦截器EncryptionFilter 前端请求拦截器添加整体加密逻辑请求头中添加sessionId 响应拦截器添加整体解密逻辑 简述 本文网关gateway&#xff0c;微服务&a…

[C语言]指针进阶详解

指针是C语言的精髓所以内容可能会比较多&#xff0c;需要我们认真学习 目录 1、字符指针 2、指针数组 3、数组指针 3.1数组指针的定义 3.2&数组名vs数组名 3.3数组指针的使用 4、数组传参和指针传参 4.1一维数组传参 4.2二维数组传参 4.3一级指针传参 4.4二级指…

学习如何使用PyQt5实现notebook功能

百度搜索“pyqt5中notebook控件”&#xff0c;AI自动生成相应例子的代码。在 PyQt5 中&#xff0c;QTabWidget 类被用作 Notebook 控件。以下是一个简单的示例&#xff0c;展示如何创建一个带有两个标签的 Notebook 控件&#xff0c;并在每个标签中放置一些文本。 import sys f…

45. UE5 RPG 增加角色受击反馈

在前面的文章中&#xff0c;我们实现了对敌人的属性的初始化&#xff0c;现在敌人也拥有的自己的属性值&#xff0c;技能击中敌人后&#xff0c;也能够实现血量的减少。 现在还需要的就是在技能击中敌人后&#xff0c;需要敌人进行一些击中反馈&#xff0c;比如敌人被技能击中后…

使用macof发起MAC地址泛洪攻击

使用macof发起MAC地址泛洪攻击 MAC地址泛洪攻击原理&#xff1a; MAC地址泛洪攻击是一种针对交换机的攻击方式&#xff0c;目的是监听同一局域网中用户的通信数据。交换机的工作核心&#xff1a;端口- MAC地址映射表。这张表记录了交换机每个端口和与之相连的主机MAC地址之间…

Spring Boot与JSP的浪漫邂逅:轻松构建动态Web应用的秘诀

本文介绍 Spring Boot 集成 JSP。 1、pom.xml 增加对 JSP 的支持 Spring Boot 的默认视图支持是 Thymeleaf 模板引擎&#xff0c;如果想要使用 JSP 页面&#xff0c;需要配置 servlet 依赖和 tomcat 的支持。 在 pom.xml 文件中增加如下代码&#xff1a; <!-- servlet依赖 -…

(六)SQL系列练习题(下)#CDA学习打卡

目录 三. 查询信息 16&#xff09;检索"1"课程分数小于60&#xff0c;按分数降序排列的学生信息​ 17&#xff09;*按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩 18&#xff09;*查询各科成绩最高分、最低分和平均分 19&#xff09;*按各科成绩…