Linux-内存文件

1. 基础IO操作

1.1 c语言的IO接口

fopen:打开一个文件,按照指定方式

参数:filename 文件名,也可以是路径,mode:打开方式

返回打开的文件指针

fread:从指定流中读数据

参数:从FILE对象中读数据,每次读size字节大小的数据,最多读count次,读的数据写在buffer里 

返回实际读的数据个数

fwrite:把数据写到指定的流中

参数 :从buffer中读数据,每次读size字节大小的数据,最多读count次,读的数据写在stream里 

返回实际写的数据个数

fclose:关闭打开的文件

不同的语言,比如c,c++,java....都有对应的IO接口,语言的底层封装的其实都是操作系统对应的IO接口,在语言层面

好处有:使用方便,学习成本低,一套接口,在不同的操作系统下都可以使用,具有跨平台可移植性

1.2 Linux的IO接口

open:打开文件

参数:pathname 路径名称,flags:标记位,打开方式,mode:文件属性(新建)

flags: 打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags。

参数:

  • O_RDONLY: 只读打开
  • O_WRONLY: 只写打开
  • O_RDWR : 读,写打开     这三个常量,必须指定一个且只能指定一个
  • O_CREAT : 若文件不存在,则创建它。需要使用mode选项(0666-umask),来指明新文件的访问权限
  • O_APPEND: 追加写
  • O_TRUNC:清空写

返回值:成功:新打开的文件描述符 失败:-1

读fd文件,写到buf里,读count字节

读buf内容,写到fd文件里,写count字节

关闭文件


2. 文件描述符fd

open函数返回值是int类型的fd,这个fd是什么呢?

我们在写代码,调用接口,然后文件被编译运行,形成进程,也就是进程在打开文件。

打开文件是进程在执行,打开文件,就是把文件从,磁盘加载到内存上,还需要一个标识符,让进程能够找到这个内存上的文件。这个标识符就是fd,file describe 文件描述符。通过fd,进程就能找到对应的文件,完成下面的操作。

一个进程,可能要打开多个文件,就会有多个fd,如何对fd进行管理呢?

而现在知道,文件描述符就是从0开始的小整数。当我们打开文件时,操作系统在内存中要创建相应的数据结构来 描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进 程和文件关联起来。

每个进程都有一个指针*files, 指向一张表files_struct,该表最重要的部分就是包涵一个指针数组,每个元素都是一个指向打开文件的指针!所以,本质上,文件描述符就是该数组的下标。所以,只要拿着文件 描述符,就可以找到对应的文件

c库默认会打开3个文件:stdin标准输入,stdout标准输出,stderr标准错误

他们的fd分别对应0(键盘),1(屏幕),2(屏幕)

接下来新建的文件,就会从3开始,依次往下,

文件描述符的分配规则:在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。


3. 文件重定向

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{close(1);int fd = open("myfile", O_WRONLY | O_CREAT | O_TRUNC, 0666);if (fd < 0){perror("open");return 1;}printf("fd: %d\n", fd);fflush(stdout);close(fd);exit(0);
}

此时,我们发现,本来应该输出到显示器上的内容,输出到了文件 myfile 当中,其中,fd=1。这种现象叫做输出重定向。常见的重定向有:>, >>, <

那重定向的本质是什么呢?

可以使用系统提供的函数接口:dup2

使用这个函数也可以达到相同的效果

dup2(3,1);

文件重定向:

输出重定向open(O_WRONLY | O_CREAT | O_APPENT)stdout重定向到新目标
追加重定向open(O_WRONLY | O_CREASE | O_TRUNC)stdout重定向到新目标
输入重定向open(O_RDONLY )stdin重定向到新目标

stdout和stderr的使用区分

stdout是用来输出打印信息,stderr一般用来输出程序的报错记录

./proc > out.txt 2> err.txt

可以分开把stdou输出的内容重定向到out.txt,stderr输出的内容重定向到err.txt

./proc > all.txt 2>&1

把两个都输出到all.txt文件中

myshell实现文件重定向

//整体结构:创建子进程,由子进程获取指令,父进程判断完成的怎么样
//1.打印标识开头
//2.获取指令字符串
//3.分析字符串提取指令到grev[]
//4.部分指令的特殊处理,例如cd
//5.替换进程execvpe
//
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>#define SIZE 1024
#define NUM 32#define EMPTY 0
#define INPUTDIR 1
#define OUTPUTDIR 2
#define APPPUTDIR 3int status_dir;char str[SIZE];
char* _grev[NUM];
char _env[NUM][NUM];char* getfile(char* str, int end)
{while(str[end] != ' '){if(str[end] == '>'){if(str[end - 1] == '>'){status_dir = APPPUTDIR;str[end-1] = '\0';return &str[end+1];}status_dir = OUTPUTDIR;str[end] = '\0';return &str[end+1];}else if(str[end] == '<'){status_dir = INPUTDIR;str[end] = '\0';return &str[end+1];}else{end--;}}return NULL;
}int main()
{int num_env = 0;status_dir = EMPTY;while(1){//1.printf("[root$loadhost myshell]# ");fflush(stdout);//2.memset(str,SIZE,'\0');fgets(str, SIZE, stdin);int sz = strlen(str);str[sz - 1] = '\0';//3.int end = sz - 2;char* file_end = getfile(str, end);_grev[0] = strtok(str, " ");int index = 1;//4.if(strcmp(_grev[0],"ls") == 0){_grev[index++] = (char*)"--color=auto";}if(strcmp(_grev[0], "ll") == 0){_grev[0] = (char*)"ls";_grev[index++] = (char*)"--color=auto";_grev[index++] = (char*)"-l";}while(_grev[index++] = strtok(NULL, " "));if(strcmp(_grev[0], "cd") == 0){if(_grev[1]) chdir(_grev[1]);continue;}if(strcmp(_grev[0], "export") == 0 && _grev[1]){memcpy(_env[num_env],_grev[1],strlen(_grev[1])+1);putenv(_env[num_env]);num_env++;continue;}pid_t id = fork();if(id < 0){perror("fork");exit(1);}else if(id == 0){//child//5int fd;switch (status_dir){case INPUTDIR:fd = open(file_end, O_RDONLY);dup2(fd,0);break;case OUTPUTDIR:fd = open(file_end, O_WRONLY | O_CREAT | O_TRUNC, 0666);dup2(fd,1);break;case APPPUTDIR:fd = open(file_end, O_WRONLY | O_CREAT | O_APPEND, 0666);dup2(fd,1);break;case EMPTY:break;default:printf("bug?\n");break;}execvp(_grev[0], _grev);exit(2);}else {//fatherint status = 0;pid_t ret = waitpid(id, &status, 0);if(ret < 0){printf("等待子进程失败\n");exit(2);}else{if(WIFEXITED(status)){printf("子进程退出码:%d\n",WEXITSTATUS(status));}else if(WIFSIGNALED(status)){printf("子进程终止信号:%d\n",WTERMSIG(status));}}}}return 0;
}

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

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

相关文章

上海亚商投顾:沪指缩量调整 油气、低空经济概念逆势走强

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指4月19日震荡调整&#xff0c;深成指跌超1%&#xff0c;创业板指盘中跌超2%。周期股逆势走强&#xff0c;油…

木马——文件上传

目录 1、WebShell 2.一句话木马 靶场训练 3.蚁剑 虚拟终端 文件管理 ​编辑 数据操作 4.404.php 5.文件上传漏洞 客户端JS检测 右键查看元素&#xff0c;删除检测代码 BP拦截JPG修改为php 服务端检测 1.MIME类型检测 2.文件幻数检测 3.后缀名检测 1、WebShell W…

将记录从excel当中导出为.sql文件,再新增到数据库

一、背景 临时遇到了一个需求&#xff0c;比如根据人员的名字查询对应记录&#xff0c;看起来还是很简单的&#xff0c;直接用select查询就可以&#xff0c;然而如果此时存在以下情况&#xff1a; 数据库根本就没有人员信息表&#xff1b;------这个倒是好操作&#xff1b;现…

SpringMVC--RESTful

1. RESTful 1.1. RESTful简介 REST&#xff1a;Representational State Transfer&#xff0c;表现层资源状态转移。 RESTful是一种网络架构风格&#xff0c;它定义了如何通过网络进行数据的交互。这种风格基于HTTP协议&#xff0c;使得网络应用之间的通信变得更加简洁和高效。…

安信可 ESP_01SWIFI模块的使用 (电脑通过usb转tll模块连接wifi模块进行调试)

一&#xff1a;需要用到的模块 &#xff08;1&#xff09;安信可的ESP_01wifi模块 ESP-01是深圳安信可科技基于ESP8266芯片开发的串口wifi模块&#xff0c;模组集成了透传功能&#xff0c;即买即用&#xff0c;支持串口指令集&#xff0c;用户通过串口即可实现网络访问…

[前端]NVM管理器安装、nodejs、npm、yarn配置

NVM管理器安装、nodejs、npm、yarn配置 NVM管理器安装 nvm(Node.js version manager) 是一个命令行应用&#xff0c;可以协助您快速地 更新、安装、使用、卸载 本机的全局 node.js 版本。 nvm下载地址&#xff1a;https://github.com/coreybutler/nvm-windows/releases 1.全部…

用全连接对手写数字识别案例(附解决TensorFlow2.x没有examples问题)

数据集介绍 数据集直接调用可能出现问题&#xff0c;建议从官网直接下载下来&#xff0c;下载存在这四个文件 手写数字识别数据集下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1nqhP4yPNcqefKYs91jp9ng?pwdxe1h 提取码&#xff1a;xe1h 55000行训练数据集&a…

git简介及安装

Git | Git简介与安装 文章目录 Git | Git简介与安装一、Git简介二、Git安装Linux-centosLinux-ubuntu 一、Git简介 存在需求&#xff1a;对于一个文档&#xff0c;由于编写思路或者当前文档丢失&#xff0c;可能存在想要历史版本的需求&#xff0c;并且需要知道每个版本都修改了…

ASP.NET Core 3 高级编程(第8版) 学习笔记 04

第 19 章主要介绍 Restful Service 的相关知识。Restful Service 的核心内容是&#xff1a;&#xff08;1&#xff09;HTTP 请求或 HTTP 动词&#xff0c;用 HTTP 请求表达不同的操作&#xff0c;最好遵守惯例。&#xff08;2&#xff09;资源&#xff0c;通过 PATH 结合 paylo…

Mogdb 5.0新特性:SQL PATCH绑定执行计划

前言 熟悉Oracle的dba都知道&#xff0c;生产系统出现性能问题时&#xff0c;往往是SQL走错了执行计划&#xff0c;紧急情况下&#xff0c;无法及时修改应用代码&#xff0c;dba可以采用多种方式针对于某类SQL进行执行计划绑定&#xff0c;比如SQL Profile、SPM、SQL Plan Base…

网络原理-IP协议

一、IP协议报头 版本号:用来表示IP协议的版本,现在常用的IP协议有两个版本,IPv4和IPv6&#xff0c;其他版本可能只存在于实验室中&#xff0c;并没有被广泛的使用。 首部长度:用来表示IP报头的长度,因为存在"选项"字段&#xff0c;所以IP报头是可变长的,此处单位为4…

软件测试之【软件测试概论一】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 前言软件生命周期软件项目开发过程软件项目组织架构软件开发相关模型 软件测试…