linux学习:文件类型、文件操作、系统IO、内存映射

目录

文件类别

文件操作

系统 IO

头文件

打开文件

关闭文件

文件描述符

读写

例子  拷贝文件

偏移量

其他接口

mmap()映射


文件类别

  • 普通文件(regular):存在于外部存储器中,用于存储普通数据。
  • 目录文件(directory):用于存放目录项,是文件系统管理的重要文件类型。
  • 管道文件(pipe):一种用于进程间通信的特殊文件,也称为命名管道 FIFO。
  • 套接字文件(socket):一种用于网络间通信的特殊文件。
  • 链接文件(link):用于间接访问另外一个目标文件,相当于 Windows 快捷方式。
  • 字符设备文件(character):字符设备在应用层的访问接口。
  • 块设备文件(block):块设备在应用层的访问接口。

文件信息的最左边一栏是各种文件类型的缩写

  • b(block)块设备文件
  • c(character)字符设备文件
  • d(directory)目录文件
  • l(link)链接文件(软链接)
  • p(pipe)管道文件(命名管道)
  • -(regular)普通文件
  • s(socket)套接字文件
  1. 块设备文件和字符设备文件,是 Linux 系统中块设备和字符设备的访问节点, 在内核中注册了某一个设备文件之后,还必须在/dev/下为这个设备创建一个对应的节点文 件(网络接口设备除外),作为访问这个设备的入口
  2. 目录文件用来存放目录项,是实现文 件系统管理的最重要的手段。
  3. 链接文件指的是软链接,是一种用来指向别的文件的特殊文件, 其作用类似于 Windows 中的快捷方式,但他有更加有用的功能,比如库文件的版本管理。
  4. 普通文件指的是外部存储器中的文件,比如二进制文件和文本文件。
  5. 套接字文件指的是本机内进程间通信用的 Unix 域套接字,或称本地域套接字。

文件操作

对一个文件的操作有两种不同的方式,既可以使用由操作系统直接提供的编程接口 (API),即系统调用,也可以使用由标准 C 库提供的标准 IO 函数

在几百个 Linux 系统调用中,有一组函数是专门针对文件操作的,比如打开文件、关 闭文件、读写文件等,这些系统调用接口就被称为“系统 IO”,相应地,在几千个标准 C 库函数中,有一组函数也是专门针对文件操作的,被称为“标准 IO”,他们是工作在不同 层次,但都是为应用程序服务的函数接口

系统 IO

头文件

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

打开文件

注意

  • flags 的各种取值可以用位或的方式叠加起来,比如创建文件的时候需要满足这样 的选项:读写方式打开,不存在要新建,如果存在了则清空他。那么此时指定的 flags 的取 值应该是:O_RDWR | O_CREAT | O_TRUNC。
  • mode 是八进制权限,比如 0644,或者 0755 等。
  • 它可以用来打开普通文件、块设备文件、字符设备文件、链接文件和管道文件,但 只能用来创建普通文件,每一种特殊文件的创建都有其特定的其他函数。
  • 其返回值就是一个代表这个文件的描述符,是一个非负整数。这个整数将作为以后任何系统 IO 函数对其操作的句柄,或称入口

关闭文件

文件描述符

是一个数组的下标值,在内核中打开的文件是用 file 结构体来表示的,每一个结构体都会有一个 指针来指向他们,这些指针被统一存放在一个叫做 fd_array 的数组当中,而这个数组被存 放在一个叫做 files_struct 的结构体中,该结构体是进程控制块 task_struct 的重要组成 部分

 

  • task_struct 被称为进程控制块,是程序运行时在 内核中的实现形式
  • 结构体 file{}是内核管理文件操作的最重要的数据之一,里面存放了对该文件的访问模 式、文件位置偏移量等重要信息。在操作文件之前,open( )参数中指定的模式将被记录在 该结构体中,在操作文件之时,文件相关的控制数据也一并在此统一管理

读写

  • 实际的读写字节数要通过返回值来判断
  • 当实际的读写字节数小于 count 时,有以下几种情形
    • 读操作时,文件剩余可读字节数不足 count
    • 读写操作期间,进程收到异步信号
  • 读写操作同时对 f_pos 起作用。也就是说,不管是读还是写,文件的位置偏移量(即 内核中的 f_pos)都会加上实际读写的字节数,不断地往后偏移

例子  拷贝文件

1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include <fcntl.h>
6 #include <unistd.h>
7
8 #define SIZE 1024
9
10 int main(int argc, char **argv)
11 {
12     int fd_from, fd_to;
13
14     if(argc != 3)
15     {
16         printf("Uage: %s <src> <dst>", argv[0]);
17         exit(1);
18     }
19     // 以只读方式打开源文件,以只写方式打开目标文件
20     fd_from = open(argv[1], O_RDONLY);
21     fd_to = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC, 0644);
22
23     char buf[SIZE];
24     char *p;
25     int nread, nwrite;
26
27     while(1)
28     {
29         nread = read(fd_from, buf, SIZE);
30
31         if(nread == 0)
32             break;
33
34         write(fd_to, buf, nread);
35     }
36
37     close(fd_from);
38     close(fd_to);
39
40     return 0;
41 }

偏移量

例子  可以实现一个进程拷贝前半段,另一个进程拷贝后半段

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdbool.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include <strings.h>
7 #include <errno.h>
8
9 #include <sys/stat.h>
10 #include <sys/types.h>
11 #include <fcntl.h>
12
13 int main(int argc, char **argv)
14 {
15     if(argc != 3) // 输入两个参数,用法类似于 Shell 命令:cp file1 file2
16     {
17         printf("Usage: %s <src> <dst>\n", argv[0]);
18         exit(1);
19     }
20
21     // 创建一个子进程(详细讲解参见第五章)
22     pid_t a = fork();
23
24     // 父子进程都打开源文件和目标文件
25     int fd1 = open(argv[1], O_RDONLY);
26     int fd2 = open(argv[2], O_CREAT|O_RDWR|O_TRUNC, 0644);
27     if(fd1 == -1 || fd2 == -1)
28     {
29         perror("open()");
30         exit(1);
31     }
32
33     int size = lseek(fd1, 0, SEEK_END); // 获得文件大小
34     if(a == 0) // 在子进程中,将位置偏移量调整到中间位置(形成空洞)
35     {
36         lseek(fd1, size/2, SEEK_SET);
37         lseek(fd2, size/2, SEEK_SET);
38     }
39     else if(a > 0) // 在父进程中,将文件位置偏移量调整到文件开头处
40     {
41         lseek(fd1, 0, SEEK_SET);
42     }
43
44     char buf[100];
45     int nread;
46
47     while(1)
48     {
49         bzero(buf, 100);
50         nread = read(fd1,bug,100);
51         if(nread==0)
52             break;
53
54         if(a > 0)
55         {
56             // 在父进程中,查看当前偏移量是否已经到达中间位置
57             int n;
58             n = lseek(fd1, 0, SEEK_CUR) - size/2;
59             if(n >= 0) // 到达甚至已经超过中间位置
60             {
61                 write(fd2, buf, n); // 写入未超过中间位置的字节
62                 exit(0); // 然后退出
63             }
64         }
65
66         write(fd2, buf, nread);
67     }
68
69     close(fd1);
70     close(fd2);
71
72     return 0;
73 }

其他接口

调整文件为异步工 作模式

int on = 1;
ioctl(fd, FIOASYNC, &on);//后面的变参也由前面的 request 命令字决定
等同于
fcntl(fd, F_SETFL, O_ASYNC);

fcntl( )而言,其第二个参数命令字 cmd 有很多

mmap()映射

该函数在进程的虚拟内存空间 中映射出一块内存区域,用以对应指定的一个文件,该内存区域上的数据跟对应的文件的数 据是一一对应的,并在一开始的时候用文件的内容来初始化这片内存

例子  使用 mmap( )实现类似 Shell 命令 cat 的功能:将一个普通文件的内容显示到屏幕上

1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <errno.h>
5
6 #include <sys/stat.h>
7 #include <sys/mman.h>
8 #include <sys/types.h>
9 #include <fcntl.h>
10
11 int main(int argc, char **argv)
12 {
13     if(argc != 2)
14     {
15         printf("Usage: %s <filename>\n", argv[0]);
16         exit(1);
17     }
18
19     // 以只读方式打开一个普通文件
20     int fd = open(argv[1], O_RDONLY);
21
22     // 申请一块大小为 1024 字节的映射内存,并将之与文件 fd 相关联
23     char *p = mmap(NULL, 1024, PROT_READ, 24 MAP_PRIVATE, fd, 0);
25
26     // 将该映射内存的内容打印出来(即其相关联文件 fd 的内容)
27     printf("%s\n", p);
28
29     return 0;
30 }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯,,,,,,

辗转相除求最大公约数 #include<iostream> using namespace std;int gcd(int a, int b)//求最大公约数&#xff0c;如果返回值为1&#xff0c;最大公约数只有1&#xff0c;为所求 {return b ? gcd(b, a % b) : a; } int main() {int count 0;for(int i1;i<2020;i)f…

进口PFA容量瓶高纯透明聚四氟乙烯材质耐强酸碱PFA定容瓶

PFA容量瓶&#xff0c;也叫特氟龙容量瓶&#xff0c;是用于配制标准浓度溶液的实验室器皿&#xff0c;是有着细长颈、梨形肚的耐强腐蚀平底塑料瓶&#xff0c;颈上有标线&#xff0c;可直接配置标准溶液和准确稀释溶液以及制备样品溶液。 因其有着不易碎、材质纯净、化学稳定性…

Unity Android后处理AO报错

整体流程&#xff1a; 1.添加AO效果 2.Mode 选择 Multi-scale Volumetric Occlusion 3.保证Project Settings - Player - Other Settings - Rendering - Graphic API 内包含 Vulkan 原因&#xff1a; 1.Post Processing文档&#xff1a;https://docs.unity3d.com/Packages/…

探索点云与KD-Tree配对的方法

比较点云是处理和分析点云数据的关键步骤。然而,由于各个扫描之间固有的差异,无法进行逐点比较。因此,点云分析的第一步也是主要步骤是将点配对以进行有意义的比较。 配对点是区分表面变形和运动分析的关键任务。这个过程不仅为变形分析提供了见解,还使我们能够通过比较不…

如何用 Readwise Reader 定制提示词 AI 自动辅助处理信息?

抵御「信息过载」&#xff0c;你需要这样的利器。 痛点 知识工作者的痛点是非常明显的——如果你是一名老师、学生&#xff0c;或是平时需要跟许多资料打交道的人&#xff0c;想必你会经历过信息过载。 信息过载有时候不仅是数量问题&#xff0c;还是一个类型问题。很多不同的信…

【话题】AI技术创业有那些机会,简单探讨下

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读小5的系列文章&#xff0c;这是《话题》系列文章 目录 背景机会一、引言二、AI技术的创业机遇1.智能服务行业的兴起2.数据驱动的业务模式创新3.AI与产业融合的创新发展 三、AI技术创业的挑战1.技术门槛高2.法规政策的不确定性…

奎芯科技:智能时代的芯片上游企业如何突破?

半导体IP&#xff08;Intellectual Property&#xff0c;知识产权&#xff09;&#xff0c;通常也称作IP核&#xff08;IP core&#xff09;&#xff0c;指芯片设计中预先设计、验证好的功能模块&#xff0c;主要服务于芯片设计&#xff0c;因部分通用功能模块在芯片中被反复使…

03-JAVA设计模式-享元模式

享元模式 什么是享元模式 享元模式&#xff08;Flyweight Pattern&#xff09;是一种对象结构型设计模式&#xff0c;用于减少创建对象的数量&#xff0c;以减少内存占用和提高系统性能。它通过共享已经存在的对象来避免创建大量相似的对象&#xff0c;从而降低内存消耗。 在…

SAP 计划策略82简介

前面的文章中我们已经测试了很多才策略,10、11、40、50、70、60、63 80策略。 本文将重点说明ATO模式下82策略的使用场景,计划策略82是SAP提供的另一种基于按单生产思想的计划策略,由客户的需求来直接驱动直接生产,是一个按单生产的场景。 1、首先我们先看下系统后台82策略…

为什么都在做白银投资?略谈现货白银的投资优势

在各种主要的投资产品中&#xff0c;现货白银可以说是比较具有优势的一种。近期现货白银价格不断攀升&#xff0c;已经突破了28.00大关&#xff0c;这更是引起了很多朋友对现货白银投资的兴趣。下面我们就来讨论一下&#xff0c;现货白银的投资优势有哪些。 交易灵活。投资现货…

嵌入式岗位“面试失败”的宝贵经验分享

面试失败&#xff0c;在所难免。从中汲取教训和经验才最关键。面试并不只是用人单位挑选应聘者&#xff0c;同样也是应聘者从面试中获取相关工作信息的好渠道。 1.每面完一次试&#xff0c;认真回顾整个面试 很多人面试一出来&#xff0c;就像考完一场试一样&#xff0c;把…

专访安霸CEO王奉民:怎么帮助OEM在智驾上和特斯拉竞争

采访| 德新 撰文| 苗岭 整个2023年&#xff0c;安霸CEO王奉民两次到访中国&#xff0c;一次是参加上海车展&#xff1b;另一次&#xff0c;他拜访了所有能约上的主机厂及Tier 1客户。 王奉民积极地出现在国内&#xff0c;跟安霸当前押注汽车领域有关。 这家成立于2004年的芯…

鸿蒙内核源码分析 (物理内存篇) | 怎么管理物理内存

如何初始化物理内存&#xff1f; 鸿蒙内核物理内存采用了段页式管理&#xff0c;先看两个主要结构体。结构体的每个成员变量的含义都已经注解出来&#xff0c;请结合源码理解. #define VM_LIST_ORDER_MAX 9 //伙伴算法分组数量&#xff0c;从 2^0&#xff0c;2^1&#…

我的小程序接口被刷爆了

自然流量的惊喜 书接上文&#xff0c;凭着短视频的好奇&#xff0c;搭了个小程序&#xff0c;做了文案提取&#xff0c;配音等功能&#xff0c;也顺带写了两篇口水文章&#xff0c;不曾想居然收获历史最高的点赞与收藏。有兴趣的朋友可以点这里一看究尽&#xff1a;《短视频配音…

ZL-WK-4五孔注意力测试系统

简单介绍&#xff1a; 五孔注意力测试系统基于视觉上的辨别力&#xff0c;通过运行5-CSRTT任务(5-choice serial reaction time task)&#xff0c; 测试动物的注意力、冲动性(impulsivity)等一系列行为学指标&#xff0c;主要用于注意力缺失/多动综合症(attention deficit/hype…

若依框架判断是否关闭了某个页面,或者在关闭某个页面进行操作

src\plugins\tab.js // 关闭指定tab页签closePage(obj) {console.log(obj,obj)if (obj undefined) {return store.dispatch(tagsView/delView, router.currentRoute).then(({ lastPath }) > {return router.push(lastPath || /);});}if(obj.fullPath "/plugin/workfl…

RabbitMQ消息模型之Fanout消息模型

Fanout消息模型 * 广播模型&#xff1a;* 一个交换机绑定多个队列* 每个队列都有一个消费者* 每个消费者消费自己队列中的消息&#xff0c;每个队列的信息是一样的生产者 package com.example.demo02.mq.fanout;import com.example.demo02.mq.util.ConnectionUtils; impor…

2023年金融贷款骗局套路之一

源地址&#xff1a;2023年金融贷款骗局套路之一_预防网贷套路_计算机技术网 随着无卡消费的日夜流行&#xff0c;三年疫情出现&#xff0c;钱难寻&#xff0c;难找的尴尬境地&#xff0c;贷款骗局也出现不少。今天我们讲讲最近很流行的贷款骗局之一中的一种贷款骗局。 在平常…

C++设计模式|0.前言

1.什么是设计模式&#xff1f; 简答来说&#xff0c;设计模式就是一套好用的代码经验总结&#xff0c;也就是怎么写好代码的方法论。使用设计模式是为了可重用代码、让代码更容易被他人理解、提高代码的可靠性。 2.设计模式的分类 设计模式可以分为三类&#xff1a;创建型、…