Linux应用开发基础知识——文件IO操作(三)

前言:

在 Linux 系统中,一切都是“文件”:普通文件、驱动程序、网络通信等等。 所有的操作,都是通过“文件 IO”来操作的。所以,很有必要掌握文件操作的常用接口。

目录

一、文件IO

1.什么是文件:

2.怎么知道这些函数的用法?

3.文件IO的分类

二、使用open函数打开文件

1.用man命令进行查看文件使用方法

 2.open.c 源码如下:

 三、使用open函数创建文件

 create.c 源码如下:

四、使用write函数写文件

1.用man命令进行查看文件使用方法

 2 .write.c 源码如下:

五、lseek中间插入

1.用man命令进行查看文件使用方法

2 .write_in_poc.c 源码如下:

​编辑 六、读写文件

1.通用的 IO 模型:open/read/write/lseek/close

 2.不是通用的函数:ioctl/mmap

七、内核接口

1.系统调用函数怎么进入内核?

2.内核的 sys_open、sys_read 会做什么? 


        这 2 本书的内容类似,第一本对知识点有更细致的描述,适合初学者;第二 本比较直接,一上来就是各种函数的介绍,适合当作字典,不懂时就去翻看一下。 做纯 Linux 应用的入门,看这 2 本书就可以了,我们的侧重于“嵌入式 Linux”。 

一、文件IO

1.什么是文件:

        Linux 的文件既可以是真实保存到存储介质的文件也可以 是自身内核提供的虚拟文件,还可以是设备节点。

2.怎么知道这些函数的用法?

Linux 下有 3 大帮助方法:help、man、info

想查看某个命令的用法时,比如查看 ls 命令的用法,可以执行:

ls --help

 help 只能用于查看某个命令的用法,而 man 手册既可以查看命令的用法,还可以查看函数的详细介绍等等。它含有 9 大分类,如下:

1 Executable programs or shell commands // 命令
2 System calls (functions provided by the kernel) // 系统调用,比如 man 2 open
3 Library calls (functions within program libraries) // 函数库调用
4 Special files (usually found in /dev) // 特殊文件, 比如 man 4 tty 
5 File formats and conventions eg /etc/passwd // 文件格式和约定, 比如 man 5 passwd
6 Games // 游戏
7 Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7) //杂项
8 System administration commands (usually only for root) // 系统管理命令
9 Kernel routines [Non standard] // 内核例程

        比如想查看 open 函数的用法时,可以直接执行“man open”,发现这不是 想要内容时再执行“man 2 open”。

        在 man 命令中可以及时按“h”查看帮助信息了解快捷键。常用的快捷键是: 

f 往前翻一页
b 往后翻一页
/patten 往前搜
?patten 往后搜

         就内容来说,info 手册比 man 手册编写得要更全面,但 man 手册使用起来 更容易些。

        以书来形容 info 手册和 man 手册的话,info 手册相当于一章,里面含有若干节,阅读时你需要掌握如果从这一节跳到下一节;而 man 手册只相当于一节, 阅读起来当然更容易。

3.文件IO的分类

标准IO:   fopen/fread/fwrite/fseek/fflush/fclose

系统IO: open/read /write/lseek/close
 

这2种IO函数的区别: 

二、使用open函数打开文件

1.用man命令进行查看文件使用方法

man 2 open

函数作用:

作用:打开或者创建一个文件

pathname: 文件路径名,或者文件名

flags:表示打开文件所采用的操作


O_RDONLY:只读模式
O_WRONLY:只写模式

O_RDWR:可读可写 
O_APPEND:表示追加,如果原来文件里面有内容,则这次写入会写在文件的最末尾。 
O_REAT:表示如果指定文件不存在,则创建这个文件
O_EXCL:表示如果要创建的文件已存在,则出错,同时返回--1,并且修改·errno·的值。
O_TRUNC:表示截断,如果文件存在,并且以只写、读写方式打开,则将其长度截断为0。“

 2.open.c 源码如下:


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
/*
*./open_ 1.txt
*argc    = 2
*argv[0] = "./open"
*argv[1] = "1.txt"
*/
int main(int argc, char **argv)
{int fd;if(argc != 2){printf("Uage:%s <file>\n",argv[0]);return -1;}fd = open(argv[1],O_RDWR);if (fd < 0){printf("can not open file %s\n",argv[1]);printf("errno = %d\n",errno);printf("err: %s\n",strerror(errno));perror("open");}else{printf("fd = %d\n",fd);}while(1){sleep(10);}close(fd);return 0;
}

 三、使用open函数创建文件

设置创建文件并开启权限

fd = open(argv[1],O_RDWR | O_CREAT | O_TRUNC,0644);

 create.c 源码如下:


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
/*
*./create   1.txt
*argc    = 2
*argv[0] = "./create"
*argv[1] = "1.txt"
*/
int main(int argc, char **argv)
{int fd;if(argc != 2){printf("Uage:%s <file>\n",argv[0]);return -1;}fd = open(argv[1],O_RDWR | O_CREAT | O_TRUNC,0644);if (fd < 0){printf("can not open file %s\n",argv[1]);printf("errno = %d\n",errno);printf("err: %s\n",strerror(errno));perror("open");}else{printf("fd = %d\n",fd);}while(1){sleep(10);}close(fd);return 0;
}

四、使用write函数写文件

1.用man命令进行查看文件使用方法

 2 .write.c 源码如下:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
/*
*./write   1.txt  str1 str2
*argc    >= 3
*argv[0] = "./write"
*argv[1] = "1.txt"
*/
int main(int argc, char **argv)
{int fd;int i;int len;if(argc < 3){printf("Uage:%s <file> <string1> <string2> ...\n",argv[0]);return -1;}fd = open(argv[1],O_RDWR | O_CREAT | O_TRUNC,0644);if (fd < 0){printf("can not open file %s\n",argv[1]);printf("errno = %d\n",errno);printf("err: %s\n",strerror(errno));perror("open");}else{printf("fd = %d\n",fd);}for(i = 2; i < argc; i ++){len =  write(fd,argv[i],strlen(argv[i]));if(len != strlen(argv[i])){perror("write");break;}write(fd,"\r\n",2);}close(fd);return 0;
}

五、lseek中间插入

1.用man命令进行查看文件使用方法

.write_in_poc.c 源码如下:


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
/*
*./write   1.txt  str1 str2
*argc    >= 3
*argv[0] = "./write"
*argv[1] = "1.txt"
*/
int main(int argc, char **argv)
{int fd;int i;int len;if(argc != 2){printf("Uage:%s <file>\n",argv[0]);return -1;}fd = open(argv[1],O_RDWR | O_CREAT,0644);if (fd < 0){printf("can not open file %s\n",argv[1]);printf("errno = %d\n",errno);printf("err: %s\n",strerror(errno));perror("open");}else{printf("fd = %d\n",fd);}printf("lseek to offset 3 from file head\n");lseek(fd,3,SEEK_SET);write(fd,"123",3);close(fd);return 0;
}

 六、读写文件

1.通用的 IO 模型:open/read/write/lseek/close

copy.c 源码如下:


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>/** ./copy 1.txt 2.txt* argc    = 3* argv[0] = "./copy"* argv[1] = "1.txt"* argv[2] = "2.txt"*/
int main(int argc, char **argv)
{int fd_old, fd_new;char buf[1024];int len;/* 1. 判断参数 */if (argc != 3){printf("Usage: %s <old-file> <new-file>\n", argv[0]);return -1;}/* 2. 打开老文件 */fd_old = open(argv[1], O_RDONLY);if (fd_old == -1){printf("can not open file %s\n", argv[1]);return -1;}/* 3. 创建新文件 */fd_new = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);if (fd_new == -1){printf("can not creat file %s\n", argv[2]);return -1;}/* 4. 循环: 读老文件-写新文件 */while ((len = read(fd_old, buf, 1024)) > 0){if (write(fd_new, buf, len) != len){printf("can not write %s\n", argv[2]);return -1;}}/* 5. 关闭文件 */close(fd_old);close(fd_new);return 0;
}
book@100ask:~/source/06_fileio$ gcc -o copy copy.c
book@100ask:~/source/06_fileio$ ./copy copy.c new.c

 2.不是通用的函数:ioctl/mmap

copy_mmap.c 源码如下:


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>/** ./copy 1.txt 2.txt* argc    = 3* argv[0] = "./copy"* argv[1] = "1.txt"* argv[2] = "2.txt"*/
int main(int argc, char **argv)
{int fd_old, fd_new;struct stat stat;char *buf;/* 1. 判断参数 */if (argc != 3){printf("Usage: %s <old-file> <new-file>\n", argv[0]);return -1;}/* 2. 打开老文件 */fd_old = open(argv[1], O_RDONLY);if (fd_old == -1){printf("can not open file %s\n", argv[1]);return -1;}/* 3. 确定老文件的大小 */if (fstat(fd_old, &stat) == -1){printf("can not get stat of file %s\n", argv[1]);return -1;}/* 4. 映射老文件 */buf = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd_old, 0);if (buf == MAP_FAILED){printf("can not mmap file %s\n", argv[1]);return -1;}/* 5. 创建新文件 */fd_new = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);if (fd_new == -1){printf("can not creat file %s\n", argv[2]);return -1;}/* 6. 写新文件 */if (write(fd_new, buf, stat.st_size) != stat.st_size){printf("can not write %s\n", argv[2]);return -1;}/* 5. 关闭文件 */close(fd_old);close(fd_new);return 0;
}
book@100ask:~/source/06_fileio$ gcc -o copy_mmap copy_mmap.c
book@100ask:~/source/06_fileio$ ./copy_mmap copy_mmap.c new2.c

七、内核接口

1.系统调用函数怎么进入内核?

        以 open/read 为例,从用户态调用 API 触发异常进入内核的过程,最后调用的 sys_call_table 的函数指针数组如下:

2.内核的 sys_open、sys_read 会做什么? 

        进入内核后,sys_read/open 会首先根据参数判断文 件的类型,然后根据不同的文件类型去找不同的设备驱动,继而进行读写或者输 入输出控制。

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

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

相关文章

【Android】画面卡顿优化列表流畅度一

卡顿渲染耗时如图&#xff1a; 卡顿表现有如下几个方面&#xff1a; 网络图片渲染耗时大上下滑动反应慢&#xff0c;甚至画面不动新增一页数据加载渲染时耗时比较大&#xff0c;上下滑动几乎没有反应&#xff0c;画面停止没有交互响应 背景 实际上这套数据加载逻辑已经运行…

绝对力作:解锁string的所有关键接口,万字深度解析!

W...Y的主页 &#x1f60a; &#x1f354;前言&#xff1a; 通过博主的上篇文章&#xff0c;我相信大家已经认识了STL并且已经迫不及待想学习了&#xff0c;现在我们就走近STL的第一种类——string。 目录 为什么学习string类&#xff1f; C语言中的字符串 标准库中的str…

【机器学习】梯度下降预测波士顿房价

文章目录 前言一、数据集介绍二、预测房价代码1.引入库2.数据3.梯度下降 总结 前言 梯度下降算法学习。 一、数据集介绍 波士顿房价数据集&#xff1a;波士顿房价数据集&#xff0c;用于线性回归预测 二、预测房价代码 1.引入库 from sklearn.linear_model import Linear…

筹码穿透率指标选股公式,衡量筹码抛压

在前面的文章中&#xff0c;介绍了博弈K线&#xff0c;它是根据筹码分布的原理结合普通K线的方法绘制出来的。当博弈K线的实体部分比较长的时候&#xff0c;说明当天穿越筹码密集区&#xff0c;有大量的筹码解套。通过引入换手率&#xff0c;可以衡量套牢盘的抛压程度。如果穿越…

Xcode 最好用的 11 个快捷键

今天来分享一下我觉得很好用的 Xcode 12 个快捷键 1. Command Shift O 快速打开&#xff0c;可让你快速导航到项目中的任何文件、函数、变量 2. Command Shift J 快速定位到当前代码所在的文件夹位置&#xff0c;并切换到项目导航器中显示 3. Command Shift Y 快速…

2011年03月31日 Go生态洞察:Godoc —— Go代码的文档化

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

list部分接口模拟实现(c++)

List list简介list基本框架list构造函数list_node结构体的默认构造list类的默认构造 push_back()iteartor迭代器迭代器里面的其他接口const迭代器通过模板参数实现复用operator->() insert()erase()clear()析构函数迭代器区间构造拷贝构造operator() list简介 - list可以在…

【Java】本地开发环境正常、测试或生产环境获取的文件路径不对的问题

引 Java 中经常获取本地文件或者resource下的文件&#xff0c;要获取文件&#xff0c;首先要获得本地路径。 Java 本身或一些开源工具包都提供了很多获取路径的方法。但使用时经常遇到本地开发环境正常、测试或生产环境获取的文件路径不对的问题。 本文将列出几种常见的获取…

python开发过程中注意编码规范~

文章目录 一、 代码编排二、 文档编排三、 空格的使用四、 注释五、 文档描述六、 命名规范总体原则&#xff0c;新编代码必须按下面命名风格进行&#xff0c;现有库的编码尽量保持风格。七 编码建议关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、…

【三维重建】摄像机几何

针孔相机模型 为了方便我们对针孔相机模型进行数学建模&#xff0c;我们往往对虚拟像平面进行研究&#xff0c;因为虚拟像平面的方向与我们实际物体的方向一致。 通过相似三角形法可以得到三维坐标到二维坐标映射 将像平面原点坐标移动到左下角&#xff1a; 加上现实世界单位&a…

【神经网络】【GoogleNet】

1、引言 卷积神经网络是当前最热门的技术&#xff0c;我想深入地学习这门技术&#xff0c;从他的发展历史开始&#xff0c;了解神经网络算法的兴衰起伏&#xff1b;同时了解他在发展过程中的**里程碑式算法**&#xff0c;能更好的把握神经网络发展的未来趋势&#xff0c;了解神…

【Linux笔记】Linux环境变量与地址空间

【Linux笔记】Linux环境变量与地址空间 一、命令行参数1.1、main函数的参数1.2、main函数的第三个参数 二、环境变量的概念与内容2.1、环境变量的概念2.2、环境变量的分类2.3、环境变量的组织形式2.4、常见的环境变量 三、设置环境变量3.1、通过命令获取或设置环境变量3.2、通过…

补偿 FIR 滤波器引入的延迟

补偿 FIR 滤波器引入的延迟 对信号进行滤波会引入延迟。这意味着相对于输入&#xff0c;输出信号在时间上有所偏移。此示例向您说明如何抵消这种影响。 有限冲激响应滤波器经常将所有频率分量延迟相同的时间量。这样&#xff0c;我们就很容易通过对信号进行时移处理来针对延迟…

SMART PLC模拟量上下限报警功能块(梯形图代码)

博途PLC模拟量偏差报警功能块请参考下面的文章链接: 模拟量偏差报警功能块(SCL代码)_RXXW_Dor的博客-CSDN博客文章浏览阅读594次。工业模拟量采集的相关基础知识,可以查看专栏的系列文章,这里不再赘述,常用链接如下:PLC模拟量采集算法数学基础(线性传感器)_plc傳感器數…

目标检测算法 - YOLOv1

文章目录 1. 作者简介2. 目标检测综述3. YOLOv1算法3.1 预测阶段3.2 预测阶段后处理3.3 训练阶段 YOLO的全称是you only look once&#xff0c;指只需要浏览一次就可以识别出图中的物体的类别和位置。 YOLO是目标检测模型。目标检测是计算机视觉中比较简单的任务&#xff0c;用…

OpenHarmony创新赛|赋能直播第五期

OpenHarmony创新赛赋能直播课程即将再次与大家见面&#xff01;本期基于之前的青蛙影院的UI界面设计的课程&#xff0c;介绍综合性APP的需求介绍和技术栈整合等内容。此外&#xff0c;课程同步赋能OpenHarmony创新赛&#xff0c;为参赛开发者带来新的思路和方法&#xff0c;也欢…

卷积神经网络中 6 种经典卷积操作

深度学习的模型大致可以分为两类&#xff0c;一类是卷积神经网络&#xff0c;另外一类循环神经网络&#xff0c;在计算机视觉领域应用最多的就是卷积神经网络&#xff08;CNN&#xff09;。CNN在图像分类、对象检测、语义分割等经典的视觉任务中表现出色&#xff0c;因此也早就…

【Python3】【力扣题】242. 有效的字母异位词

【力扣题】题目描述&#xff1a; 【Python3】代码&#xff1a; 1、解题思路&#xff1a;若字符串长度相同&#xff0c;依次遍历元素&#xff0c;比较两个字符串的该元素个数是否相同。【耗时长】 知识点&#xff1a;len(...)&#xff1a;获取序列&#xff08;字符串、列表等&…

【uniapp】通用列表封装组件

uniapp页面一般都会有像以下的列表页面&#xff0c;封装通用组件&#xff0c;提高开发效率&#xff1b; &#xff08;基于uView前端框架&#xff09; 首先&#xff0c;通过设计图来分析一下页面展示和数据结构定义 w-table组件参数说明 参数说明类型可选值默认值toggle列表是…

关于Android Studio中开发Flutter配置

配置系统环境变量&#xff1a;path下 &#xff0c;flutter的bin目录下 File->Settings->Languages&Frameworks->FlutterFile->Settings->Languages&Frameworks->DartFile->Settings->Languages&Frameworks->Android SDK 确认是…