linux系统编程-文件系统

news2024/11/28 2:53:36

目录

1文件存储

1.1 inode

1.2 dentry

2.文件系统

2.1 stat函数

2.2 lstat函数

2.3特殊权限位、黏住位

2.4 access函数

2.5 chmod函数

2.6 truncate函数

2.7 link函数

2.8 unlink函数、

2.9 隐式回收

2.10 symlink函数

2.11 readlink函数

2.12 rename函数

2.13 目录操作

 2.14 getcwd函数

2.15 chdir函数

3.文件、目录权限

3.1 opendir函数

3.2 closedir函数

3.3 readdir函数

 3.4 rewinddir函数

3.6 telldir/seekdir函数

3.7 递归遍历目录

3.8 重定向


1文件存储

首先了解如下文件存储相关概念:inode、 dentry、 数据存储、文件系统。

      

1.1 inode

其本质为结构体,存储文件的属性信息。如:权限、类型、大小、时间、用户、盘块位置……也叫作文件属性管理结构,大多数的inode都存储在磁盘上。少量常用、近期使用的inode会被缓存到内存中。

1.2 dentry

目录项,其本质依然是结构体,重要成员变量有两个 {文件名,inode,...},而文件内容(data)保存在磁盘盘块中。一个文件有两部分一部分是dentry 找到inode 号,之后再找到inode(结构体),进一步找到其在文件中的位置。给一个文件创建一个硬链接,他们有相同的inode 节点,有不同的目录项dentry.删除就是将连接数减1 ,实际就是 去掉一个dentry而已。当inode 变成0 ,原来指向会被覆盖而已。数据不能被擦除,只能被覆盖而已。只要恢复到原来的inode 即可。

 

 

         数据的恢复。

2.文件系统

文件系统是,一组规则,规定对文件的存储及读取的一般方法。文件系统在磁盘格式化过程中指定。常见的文件系统有:fat32  ntfs  exfat  ext2 、ext3 、ext4.

2.1 stat函数

获取文件属性,(从inode结构体中获取)

int stat(const char *path, struct stat *buf); 成返回0;失败返回-1 设置errno为恰当值。

 

 

参数1:文件名

参数2:inode结构体指针 (传出参数)

文件属性将通过传出参数返回给调用者。

练习:使用stat函数查看文件属性

 

2.2 lstat函数

int lstat(const char *path, struct stat *buf); 成返回0;失败返回-1 设置errno为恰当值。

练习:给定文件名,判断文件类型。 【get_file_type.c】

文件类型判断方法:st_mode 取高4位。 但应使用宏函数:           

   S_ISREG(m)   is it a regular file?

       S_ISDIR(m)   directory?

       S_ISCHR(m)   character device?

       S_ISBLK(m)   block device?

       S_ISFIFO(m) FIFO (named pipe)?

       S_ISLNK(m)   symbolic link?  (Not in POSIX.1-1996.)

       S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

穿透符号链接:stat:会;lstat:不会.

 

2.3特殊权限位

包含三个二进制位。依次是:设置组ID位setGID;设置用户ID位setID;黏住位sticky。

黏住位

早起计算机内存紧,只有精要的常用的程序可以常驻物理内存,剩下的要暂存磁盘中。当内存不够用的时候会将该部分程序存回磁盘,腾出内存空间。若文件设置了黏住位,那么即使在内存比较吃紧的情况下,也不会将该文件回存到磁盘上。由于现阶段操作系统的虚拟内存管理分页算法完善。该功能已经被废弃。

但我们仍然可以对目录设置黏住位。被设置了该位的目录,其内部文件只有:

①超级管理员

②该目录所有者

③该文件的所有者

以上三种用户有权限做删除、修改操作。其他用户可以读、创建但不能随意删除。

setUID位

进程有两个ID:EID(有效用户ID),表示进程履行哪个用户的权限。

      UID(实际用户ID),表示进程实际属于哪个用户。

多数情况下,EID和UID相同。但是,当文件的setID被设置后两个ID则有可能不一样。

例如:当进程执行一个root用户的文件,若该文件的setID位被设置为1, 那么执行该文件时,进程的UID不变。EID变为root,表示进程开始履行root用户权限。

 setGID位于setID相类似。

2.4 access函数

测试指定文件是否存在/拥有某种权限。

int access(const char *pathname,  int mode); 成功/具备该权限:0;失败/不具备 -1 设置errno为相应值。

参数2:R_OK、W_OK、X_OK

通常使用access函数来测试某个文件是否存在。F_OK。

2.5 chmod函数

修改文件的访问权限

int chmod(const char *path, mode_t mode); 成功:0;失败:-1设置errno为相应值int fchmod(int fd, mode_t mode);

2.6 truncate函数

截断文件长度成指定长度。常用来拓展文件大小,代替lseek。

       int truncate(const char *path, off_t length); 成功:0;失败:-1设置errno为相应值

       int ftruncate(int fd, off_t length);

2.7 link函数

思考,为什么目录项要游离于inode之外,画蛇添足般的将文件名单独存储呢??这样

的存储方式有什么样的好处呢?其目的是为了实现文件共享。Linux允许多个目录项共享一个inode,即共享盘块(data)。不同文件名,在人类眼中将它理解成两个文件,但是在内核眼里是同一个文件。link函数,可以为已经存在的文件创建目录项(硬链接)。int link(const char *oldpath,  const char *newpath); 成功:0;失败:-1设置errno为相应值注意:由于两个参数可以使用“相对/绝对路径+文件名”的方式来指定,所以易出错。

如:link("../abc/a.c", "../ioc/b.c")若a.c,b.c都对, 但abc,ioc目录不存在也会失败。mv命令既是修改了目录项,而并不修改文件本身。

2.8 unlink函数、

删除一个文件的目录项;int unlink(const char *pathname); 成功:0;失败:-1设置errno为相应值

练习:编程实现mv命令的改名操作 【imp_mv.c】

注意Linux下删除文件的机制:不断将st_nlink -1,直至减到0为止。无目录项对应的文件,将会被操作系统择机释放。(具体时间由系统内部调度算法决定)因此,我们删除文件,从某种意义上说,只是让文件具备了被释放的条件。unlink函数的特征:清除文件时,如果文件的硬链接数到0了,没有dentry对应,但该文件仍不会马上被释放。要等到所有打开该文件的进程关闭该文件,系统才会挑时间将该文件释放掉【unlink_exe.c】

2.9 隐式回收

当进程结束运行时,所有该进程打开的文件会被关闭,申请的内存空间会被释放。系统的这一特性称之为隐式回收系统资源。

2.10 symlink函数

创建一个符号链接int symlink(const char *oldpath, const char *newpath); 成功:0;失败:-1设置errno为相应值。

2.11 readlink函数

读取符号链接文件本身内容,得到链接所指向的文件名。ssize_t readlink(const char *path, char *buf, size_t bufsiz); 成功:返回实际读到的字节数;失败:-1设置errno为相应值。

2.12 rename函数

重命名一个文件。int rename(const char *oldpath, const char *newpath); 成功:0;失败:-1设置errno为相应值。

2.13 目录操作

工作目录:“./”代表当前目录,指的是进程当前的工作目录,默认是进程所执行的程序所在的目录位置。

 2.14 getcwd函数

获取进程当前工作目录 (卷3,标库函数)

char *getcwd(char *buf, size_t size); 成功:buf中保存当前进程工作目录位置。失败返回NULL。

2.15 chdir函数

        

改变当前进程的工作目录。int chdir(const char *path); 成功:0;失败:-1设置errno为相应值

【imp_cd.c】

练习:获取及修改当前进程的工作目录,并打印至屏幕。

3.文件、目录权限

注意:目录文件也是“文件”。其文件内容是该目录下所有子文件的目录项dentry。 可以尝试用vim打开一个目录。

r

w

x

文件

文件的内容可以被查看

内容可以被修改

可以运行产生一个进程

cat、more、less…

vi、> …

./文件名

目录

目录可以被浏览

创建、删除、修改文件

可以被打开、进入

ls、tree…

mv、touch、mkdir…

cd

目录设置黏住位:若有w权限,创建不变,删除、修改只能由root、目录所有者、文件所有者操作。

3.1 opendir函数

        

根据传入的目录名打开一个目录 (库函数) DIR * 类似于 FILE *DIR *opendir(const char *name);   成功返回指向该目录结构体指针,失败返回NULL 参数支持相对路径、绝对路径两种方式:例如:打开当前目录:① getcwd() , opendir() ② opendir(".");

3.2 closedir函数

        关闭打开的目录 int closedir(DIR *dirp); 成功:0;失败:-1设置errno为相应值

3.3 readdir函数

        

读取目录 (库函数)struct dirent *readdir(DIR *dirp);  成功返回目录项结构体指针;失败返回NULL设置errno为相应值需注意返回值,读取数据结束时也返回NULL值,所以应借助errno进一步加以区分。

struct 结构体:

           struct dirent {

               ino_t          d_ino;      inode编号

               off_t          d_off;       

               unsigned short  d_reclen;    文件名有效长度

               unsigned char   d_type;     类型(vim打开看到的类似@*/等)

               char          d_name[256];文件名   };

       

其成员变量重点记忆两个:d_ino、d_name。实际应用中只使用到d_name。

练习1:实现简单的ls功能。 【imp_ls.c】

练习2:实现ls不打印隐藏文件。每5个文件换一个行显示。 【imp_ls2.c】

拓展1:实现ls -a -l 功能。

拓展2:统计目录及其子目录中的普通文件的个数

 3.4 rewinddir函数

回卷目录读写位置至起始。

        void rewinddir(DIR *dirp); 返回值:无。

3.6 telldir/seekdir函数

获取目录读写位置

long telldir(DIR *dirp); 成功:与dirp相关的目录当前读写位置。失败-1,设置errno修改目录读写位置

void seekdir(DIR *dirp, long loc); 返回值:无参数loc一般由telldir函数的返回值来决定。

       

3.7 递归遍历目录

查询指定目录,递归列出目录中文件,同时显示文件大小。 【ls_R.c】

3.8 重定向

dup 和 dup2函数

int dup(int oldfd); 成功:返回一个新文件描述符;失败:-1设置errno为相应值

        int dup2(int oldfd, int newfd);

记忆方法两种:1. 文件描述符的本质角度理解记忆。2. 从函数原型及使用角度,反向记忆。练习:借助dup函数编写mycat程序,实现cat file1 > file2 命令相似功能。 【mycat.c】

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

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

相关文章

Java 常用的重构技巧指南 v1.0

前段时间,leader 在 review 代码的时候发现了代码中 存在的一部分的问题,导致 代码的复杂度太高了,包括大部分的sql 都是属于慢sql ,还是在建立了索引的情况下 , 代码的流程过于臃肿,而且本人编码的习惯,习…

Mybatis-Plus(一)--Mybatis-Plus介绍与快速入门

阅读这篇文章之前确保你已经学过springboot和mybatis 一.Mybtis-Plus介绍 【1】Mybatis-Puls(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发,提高效率而生。 简单说就是其实很多sql语…

IntelliJ IDEA下载安装教程

目录 友情提醒第一章、IDEA软件下载1.1)官网下载 第二章、IDEA软件安装2.1)以"ideaIU-2018.3.3.exe"为例3.2)启动IDEA软件 友情提醒 点击文章目录可以跳转 第一章、IDEA软件下载 IDEA 全称 IntelliJ IDEA。在智能代码助手、代码…

字节跳动春招研发部分编程题汇总

状压dp(不会) http://t.csdn.cn/W9Pi2 #include <iostream> #include<string.h> #include<math.h> using namespace std; char a[1005]; char c[1005]; int main() {int n;scanf("%d",&n);for(int i1;i<n;i){scanf("%s",a);int l…

Pytorch学习笔记(1)

目录 1. 张量&#xff08;Tensors&#xff09; 2. 自动求导&#xff08;Automatic Differentiation&#xff09; 3. 神经网络的构建和训练 送书活动 PyTorch是一个基于Python的开源机器学习库&#xff0c;广泛应用于深度学习和人工智能领域。它提供了丰富的工具和函数&…

什么是域服务(NETBASE第十一课)

域服务(NETBASE第十一课) web虚拟主机(一台服务器运行多个WEB站点) Web虚拟主机的实现方法&#xff1a; 1&#xff09;同IP不同端口&#xff08;基于端口的虚拟主机&#xff09; 2&#xff09;同端不同IP&#xff08;基于IP的虚拟主机&#xff09; 3&#xff09;同端口同I…

使用typora+PicGo+Gitee简单实现图片上传功能

本文通过配置PicGoGitee来实现typora图片上传功能&#xff0c;系统是window 注意下载的清单有&#xff1a;PicGo&#xff0c;node.js&#xff0c;配置有&#xff1a;PicGo&#xff0c;node.js&#xff0c;gitee&#xff0c;typora 看着复杂实际上并不难&#xff0c;只是繁琐&am…

OLLVM虚假控制流源码分析

文章目录 runOnFunction函数bogus函数目前源码&#xff1a;addBogusFlow函数1createAlteredBasicBlock函数原基本块&#xff1a;copy的基本块&#xff1a; addBogusFlow函数2 runOnFunction函数 if (ObfTimes < 0) {errs()<<"BogusControlFlow application numb…

缓存淘汰策略

LRU 与 LFU 缓存策略及其实现。 应用层缓存 鉴于磁盘和内存读写的差异性&#xff0c;DB 中低频写、高频读的数据适合放入内存中&#xff0c;直接供应用层读写。在项目中读取用户资料时就使用到了 LRU&#xff0c;而非放到 Redis 中。 缓存的 2 个基本实现 Set(key string, v…

RandLA-Net 复现

GPU3090 CUDA12 1、代码 [github地址] git clone --depth1 https://github.com/QingyongHu/RandLA-Net && cd RandLA-Net 2、虚拟环境中配置&#xff1a; 在跑代码的时候出现错误&#xff1a;open3d.so文件中函数报错。查看open3d版本发现不是要求的0.3版本&#xff…

基于PyQt5的UI界面开发——信号与槽

信号与槽的机制 PyQt5采用了一种被称为“信号与槽”机制的编程模式&#xff0c;用于处理对象间的通信和事件处理。在PyQt5中&#xff0c;信号&#xff08;signal&#xff09;是对象发出的特定事件&#xff0c;例如按钮被点击、文本被修改等。而槽&#xff08;slot&#xff09;…

攻不下dfs不参加比赛(十七)

标题 为什么练dfs题目为什么练dfs 相信学过数据结构的朋友都知道dfs(深度优先搜索)是里面相当重要的一种搜索算法,可能直接说大家感受不到有条件的大家可以去看看一些算法比赛。这些比赛中每一届或多或少都会牵扯到dfs,可能提到dfs大家都知道但是我们为了避免眼高手低有的东…

WooCommerce企业级电子商务需要了解的事情

建立成功的企业业务变得比以往任何时候都容易得多。借助各种可用的平台&#xff0c;将您的想法付诸实践是绝对可行的。 “WooCommerce 是最知名的 WordPress 网站电子商务平台之一。” 它于 2011 年推出&#xff0c;自此受到大型和小型企业的欢迎。它的流行主要归功于其各种免费…

【接口流程分析】唯品会WEB端

唯品会WEB端 来看看唯品会是怎么回事&#xff0c; 地址&#xff1a;aHR0cHM6Ly93d3cudmlwLmNvbS8 https://github.com/Guapisansan/gpss_learn_reverse 代码在这里&#xff0c;会持续更新逆向案例 免责声明&#xff1a; 此文档&#xff0c;以及脚本&#xff0c;仅用来对技术的…

七年老程序员的五六月总结:十一件有意义的事

你好&#xff0c;我是拭心&#xff0c;一名工作七年的安卓开发。 每两个月我会做一次总结&#xff0c;记下这段时间里有意义的事和值得反复看的内容&#xff0c;为的是留一些回忆、评估自己的行为、沉淀有价值的信息。 最近两周的我一直处于“战斗“状态&#xff0c;同时做好…

未来驾驶新标配;CarLuncher车载开发塑造智能娱乐导航系统

车载开发在新能源汽车的快速市场占有率增长背景下具有广阔的前景。随着环境保护意识的增强和政府对清洁能源的支持&#xff0c;新能源汽车&#xff08;如电动汽车&#xff09;在全球范围内呈现出快速增长的趋势。这种趋势为车载开发提供了许多机会和潜在市场。 新能源汽车的普…

一文搞定 Postman 接口自动化测试(全网最全版)

0 前言 本文适合已经掌握 Postman 基本用法的读者&#xff0c;即对接口相关概念有一定了解、已经会使用 Postman 进行模拟请求等基本操作。 工作环境与版本&#xff1a; Window 7&#xff08;64位&#xff09;Postman &#xff08;Chrome App v5.5.3&#xff09; P.S. 不同…

数据结构day3(2023.7.17)

一、Xmind整理&#xff1a; 二、课上练习&#xff1a; 练习1&#xff1a;时间复杂度 时间复杂度&#xff1a;只保留最高阶f(n)3*n^2n^2100nT(n)O(3*n^3n^2100n)O(3*n^3)O(n^3)1>O(1):常数阶int ta; 1ab; 1at; 1f(n)3T(n)O(3)O(3*n^0)O(n^0)O(1)2>O(n): 线性阶for…

selenium:鼠标模拟操作ActionChains

ActionChains 1.导入ActionChains包 from selenium.webdriver import ActionChains 2. 执行原理 调用ActionChains的方法时&#xff0c;不会立即执行&#xff0c;而是将所有的操作,按顺序存放在一个队列里&#xff0c;当你调用perform()方法时&#xff0c;队列中的事件…

EMC学习笔记(十五)射频PCB的EMC设计(二)

射频PCB的EMC设计&#xff08;二&#xff09; 1.滤波1.1 电源和控制线的滤波1.2 频率合成器数据线、时钟线、使能线的滤波 2.接地2.1 接地分类2.2 大面积接地2.3 分组就近接地2.4 射频器件接地2.5 接地时应该注意的问题2.6 接地平面的分布 1.滤波 1.1 电源和控制线的滤波 随着…