嵌入式Linux应用开发-文件 IO

news2024/11/24 13:43:41

嵌入式Linux应用开发-文件 IO

  • 第四章 文件 IO
    • 4.1 文件从哪来?
    • 4.2 怎么访问文件?
      • 4.2.1 通用的 IO 模型:open/read/write/lseek/close
      • 4.2.2 不是通用的函数:ioctl/mmap
    • 4.3 怎么知道这些函数的用法?
    • 4.4 系统调用函数怎么进入内核?
    • 4.5 内核的 sys_open、sys_read 会做什么?

第四章 文件 IO

参考书:
在这里插入图片描述

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

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

4.1 文件从哪来?

在这里插入图片描述

4.2 怎么访问文件?

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

使用 GIT 下载所有源码后,本节源码位于如下目录:
01_all_series_quickstart\
04_嵌入式 Linux 应用开发基础知识\source\06_fileio\copy.c

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; 
} 


本节源码完全可以在 Ubuntu 上测试,跟在 ARM 板上没什么不同。
执行以下命令编译、运行:

$ gcc -o copy copy.c 
$ ./copy copy.c new.c 

4.2.2 不是通用的函数:ioctl/mmap

使用 GIT 下载所有源码后,本节源码位于如下目录:
01_all_series_quickstart\
04_嵌入式 Linux 应用开发基础知识\source\06_fileio\copy_mmap.c

在 Linux 中,还可以把一个文件的所有内容映射到内存,然后直接读写内存即可读写文件。

 
#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; 
} 
 

本节源码完全可以在 Ubuntu 上测试,跟在 ARM 板上没什么不同。
执行以下命令编译、运行:

$ gcc -o copy_mmap copy_mmap.c 
$ ./copy_mmap copy_mmap.c new2.c 

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

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 手册只相当于一节,阅读起来当然更容易。
就个人而言,我很少使用 info 命令。
可以直接执行“info”命令后,输入“H”查看它的快捷键,在 info 手册中,某一节被称为“node”,
常用的快捷键如下:

Up Move up one line. 
Down Move down one line. 
PgUp Scroll backward one screenful. 
PgDn Scroll forward one screenful. 
Home Go to the beginning of this node. 
End Go to the end of this node. 
 
TAB Skip to the next hypertext link. 
RET Follow the hypertext link under the cursor. 
l Go back to the last node seen in this window. 
[ Go to the previous node in the document. 
] Go to the next node in the document. 
p Go to the previous node on this level. 
n Go to the next node on this level. 
u Go up one level. 
t Go to the top node of this document. 
d Go to the main 'directory' node. 

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

在这里插入图片描述

4.5 内核的 sys_open、sys_read 会做什么?

在这里插入图片描述

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

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

相关文章

基于微信小程序的健身小助手打卡预约教学系统(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;用户的功能设计为&#xff1a;管理员的功能设计为&#xff1a;健身房的功能设计为&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获…

QFrame类学习笔记

1、QFrame的作用 QFrame类继承于QWidget类&#xff0c;被QAbstractScrollArea, QLabel, QLCDNumber, QSplitter, QStackedWidget, and QToolBox等类继承。 QFrame作为许多基础控件的基类&#xff0c;提供许多成员方法给子类&#xff0c;实现子类的框架样式的设计。框架样式主要…

Android 13 定制化开发--开启相机或麦克风时,去掉状态栏上的绿色图标

Android 12 或更高版本的设备上&#xff0c;当应用使用麦克风或相机时&#xff0c;图标会出现在状态栏中。如果应用处于沉浸模式&#xff0c;图标会出现在屏幕的右上角。用户可以打开“快捷设置”&#xff0c;并选择图标以查看哪些应用当前正在使用麦克风或摄像头。图 1 显示了…

Ubuntu 安装Kafka

在本指南中&#xff0c;我们将逐步演示如何在 Ubuntu 22.04 上安装 Apache Kafka。 在大数据中&#xff0c;数以百万计的数据源生成了大量的数据记录流&#xff0c;这些数据源包括社交媒体平台、企业系统、移动应用程序和物联网设备等。如此庞大的数据带来的主要挑战有两个方面…

【数据结构】插入排序:直接插入排序、折半插入排序、希尔排序的学习知识总结

目录 1、排序的基本概念 2、直接插入排序 2.1 算法思想 2.2 代码实现 3、折半插入排序 3.1 算法思想 3.2 代码实现 4、希尔排序 4.1 算法思想 4..2 代码实现 1、排序的基本概念 排序是将一组数据按照预定的顺序排列的过程&#xff0c;排序的基本概念包括以下内容…

自学WEB后端01-安装Express+Node.js框架完成Hello World!

一、前言&#xff0c;网站开发扫盲知识 1.网站搭建开发包括什么&#xff1f; 前端 前端开发主要涉及用户界面&#xff08;UI&#xff09;和用户体验&#xff08;UX&#xff09;&#xff0c;负责实现网站的外观和交互逻辑。前端开发使用HTML、CSS和JavaScript等技术来构建网页…

数据结构--快速排序

文章目录 快速排序的概念Hoare版本挖坑法前后指针法快速排序的优化三数取中法小区间用插入排序 非递归的快速排序 快速排序的概念 快速排序是通过二叉树的思想&#xff0c;先设定一个值&#xff0c;通过比较&#xff0c;比它大的放在它的右边&#xff0c;比它小的放在它的左边…

Python中的数据常见问题

数据可视化在Python中是一个非常重要的主题&#xff0c;它可以帮助我们更好地理解和分析数据。无论是探索数据的特征&#xff0c;还是向其他人展示数据的结果&#xff0c;数据可视化都起到了关键作用。然而&#xff0c;在进行数据可视化时可能会遇到一些常见问题。本文将为您分…

基于微信小程序的同城家政服务预约系统(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

DC电源模块关于宽电压输入和输出的范围

BOSHIDA DC电源模块关于宽电压输入和输出的范围 DC电源模块是一种电子设备&#xff0c;能够将输入的直流电源转换成所需的输出电源&#xff0c;用于供电各种电子设备。其中&#xff0c;关于宽电压输入和输出的范围&#xff0c;是DC电源模块常见的设计要求之一。本文将详细介绍…

嵌入式Linux应用开发-基础知识及GCC 编译器的使用

嵌入式Linux应用开发-基础知识及GCC 编译器的使用 第一章 HelloWorld 背后没那么简单1.1 交叉编译 hello.c1.2 请回答这几个问题1.3 演示 (...) 第二章 GCC 编译器的使用2.1 配套视频内容大纲2.1.1 GCC 编译过程(精简版)2.1.2 常用编译选项2.1.3 怎么编译多个文件2.1.4 制作、使…

深度学习:模型训练过程中Trying to backward through the graph a second time解决方案

1 问题描述 在训练lstm网络过程中出现如下错误&#xff1a; Traceback (most recent call last):File "D:\code\lstm_emotion_analyse\text_analyse.py", line 82, in <module>loss.backward()File "C:\Users\lishu\anaconda3\envs\pt2\lib\site-packag…

【Unity】LODGroup 计算公式

Unity 在配置 LodGroup 时&#xff0c;其分级切换的计算方法是按照物体在相机视野中占据的比例计算的。在运行时&#xff0c;如果相机视野范围&#xff08;Field of View&#xff09;没有改变&#xff0c;那么这个值可以直接换算成物体距离相机的距离。这里就讨论下如何计算得到…

ubuntu下用pycharm专业版连接AI服务器及其docker环境

一&#xff1a;用pycharm专业版连接AI服务器 1、首先在自己电脑上新建一个文件夹&#xff0c;后续用于映射服务器上自己所要用的项目文件 2、用pycharm专业版打开该文件夹&#xff0c;作为一个项目打开 3、然后在工具->部署->配置 4、配置中形式如下&#xff1a; 点击左…

Chatbot UI集成LocalAI实现自托管的ChatGPT

本文比惯例提前了一天发&#xff0c;因为明天一早&#xff0c;老苏就踏上回乡的路了&#xff0c;三年没回老家&#xff0c;这次专门请了 2 天的假 难得回家&#xff0c;打算多陪陪家人&#xff0c;和多年不见的朋友聚聚&#xff0c;当然如果有网络条件&#xff0c;还是会正常发…

英语单词记忆学习打卡系统 微信小程序

本单词记忆系统使用了计算机语言Java和存放数据的仓库MySQL&#xff0c;采用了微信小程序模式来实现。本系统使用了框架SSM和Uni-weixin实现了单词记忆系统应有的功能&#xff0c;系统主要角色包括管理员和用户。 关键词&#xff1a;Java&#xff1b;MySQL&#xff1b;SSM  在…

Unity实现设计模式——命令模式

Unity实现设计模式——命令模式 推荐一个Unity学习设计模式很好的GitHub地址&#xff1a;https://github.com/QianMo/Unity-Design-Pattern 有非常多的Star 一、介绍 命令模式使得请求的发送者与请求的执行者之间消除耦合&#xff0c;让对象之间的调用关系更加灵活。在命令模…

聊聊零拷贝技术原理和应用

文章目录 0. 引言1. 什么是零拷贝技术 1. 零拷贝技术在不同领域的应用2.传统拷贝技术的缺点3. 零拷贝技术的原理与实现1. sendfile系统调用2. 内核缓冲区与用户缓冲区3. DMA&#xff08;Direct Memory Access&#xff09;技术4. 文件描述符传递与共享5. Direct I/O&#xff08;…

Apache shiro RegExPatternMatcher 权限绕过漏洞 (CVE-2022-32532)

漏洞描述 2022年6月29日&#xff0c;Apache 官方披露 Apache Shiro &#xff08;CVE-2022-32532&#xff09;权限绕过漏洞。 当Apache Shiro中使用RegexRequestMatcher进行权限配置&#xff0c;且正则表达式中携带"."时&#xff0c;未经授权的远程攻击者可通过构造恶…