• linux系统编程3—文件存储函数


    1、innode

    其本质为结构体,存储文件的属性信息。如:权限、类型、大小、时间、用户(ls -l查询出来的信息都放在innode里面)、盘块位置(文件内容存储在磁盘上的位置)……innode也叫作文件属性管理结构,大多数的 inode 都存储在磁盘上。
    文件名单独存储,存储文件名的地方还会有innode,这个地方叫dentry(目录项)
    创建一个文件的硬链接,它们拥有着相同的innode,只是有不同的dentry
    删除一个硬链接只是删除引用innode的链接,当删除所有的硬链接后,innode的引用值为0,但并不会删除磁盘上的内容,如果重建innode数据还会恢复
    在这里插入图片描述

    2、dentry

    目录项,其本质依然是结构体,重要成员变量有两个{文件名,inode,…},而文件内容(data)保存在磁盘盘块中。

    3、stat函数

    ​ 作用:获取文件信息

    #include  
    #include  
    #include 
    int stat(const char *path, struct stat *buf)
    	参数一:文件名
    	参数二:inode结构体指针(传出参数)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ​ 返回值:成功返回0,失败返回-1;

    stat结构体内容:

    struct stat
    {
        dev_t     st_dev;     /* ID of device containing file */文件使用的设备号
        ino_t     st_ino;     /* inode number */    索引节点号 
        mode_t    st_mode;    /* protection */  文件对应的模式,文件,目录等
        nlink_t   st_nlink;   /* number of hard links */    文件的硬连接数  
        uid_t     st_uid;     /* user ID of owner */    所有者用户识别号
        gid_t     st_gid;     /* group ID of owner */   组识别号  
        dev_t     st_rdev;    /* device ID (if special file) */ 设备文件的设备号
        off_t     st_size;    /* total size, in bytes */ 以字节为单位的文件容量   
        blksize_t st_blksize; /* blocksize for file system I/O */ 包含该文件的磁盘块的大小   
        blkcnt_t  st_blocks;  /* number of 512B blocks allocated */ 该文件所占的磁盘块  
        time_t    st_atime;   /* time of last access */ 最后一次访问该文件的时间   
        time_t    st_mtime;   /* time of last modification */ /最后一次修改该文件的时间   
        time_t    st_ctime;   /* time of last status change */ 最后一次改变该文件状态的时间   
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    例子

    struct stat sbuf;
    int a= stat("./a.c", &sbuf);
    
    	获取文件大小: sbuf.st_size
    
    	获取文件类型: sbuf.st_mode
    
    	获取文件权限: sbuf.st_mode
    	
    	printf("文件大小 %d",sbuf.st_size);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    stat结构体中的st_mode 则定义了下列数种情况:

        S_IFMT   0170000    文件类型的位遮罩(掩码),可以与stat结构体中的st_mode与运算
        S_IFSOCK 0140000    套接字
        S_IFLNK 0120000     符号连接
        S_IFREG 0100000     一般文件
        S_IFBLK 0060000     区块装置
        S_IFDIR 0040000     目录
        S_IFCHR 0020000     字符装置
        S_IFIFO 0010000     先进先出
    ​
        S_ISUID 04000     文件的(set user-id on execution)位
        S_ISGID 02000     文件的(set group-id on execution)位
        S_ISVTX 01000     文件的sticky位
    ​
        S_IRUSR(S_IREAD) 00400     文件所有者具可读取权限
        S_IWUSR(S_IWRITE)00200     文件所有者具可写入权限
        S_IXUSR(S_IEXEC) 00100     文件所有者具可执行权限
    ​
        S_IRGRP 00040             用户组具可读取权限
        S_IWGRP 00020             用户组具可写入权限
        S_IXGRP 00010             用户组具可执行权限
    ​
        S_IROTH 00004             其他用户具可读取权限
        S_IWOTH 00002             其他用户具可写入权限
        S_IXOTH 00001             其他用户具可执行权限
    ​
        上述的文件类型在POSIX中定义了检查这些类型的宏定义:
        S_ISLNK (st_mode)    判断是否为符号连接
        S_ISREG (st_mode)    是否为一般文件
        S_ISDIR (st_mode)    是否为目录
        S_ISCHR (st_mode)    是否为字符装置文件
        S_ISBLK (s3e)        是否为先进先出
        S_ISSOCK (st_mode)   是否为socket
        若一目录具有sticky位(S_ISVTX),则表示在此目录下的文件只能被该文件所有者、此目录所有者或root来删除或改名,在linux中,最典型的就是这个/tmp目录啦。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    例如

    	struct stat sbuf;
    	int a= stat("./a.c", &sbuf);
    	if(S_ISREG(sbuf.st_mode))
    	{ 
     	 printf("这个是一般文件");
    	}else if(S_ISDIR (sbuf.st_mode)){
      	 printf("这个是一个目录");
    	}else if(S_ISLNK (sbuf.st_mode)){
      	 printf("这个是一个软链接");
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    穿透符号链接:不看链接这个文件而去看链接指的内容

    默认stat函数穿透符号链接
    而lstat函数不会穿透符号链接
    cat会穿透符号链接
    ls不会穿透符号链接

    4、lstat函数

    将上面的stat函数改为lstat函数,其他的不变

    5、access函数、chmod函数、truncate函数

    • access函数:测试指定文件是否存在/拥有某种权限。
    • chmod函数:修改文件访问权限。
    • truncate函数:截断文件长度成指定长度。常用来拓展文件大小,代替lseek。

    6、link函数

    link 函数专门用来创建硬链接的,功能和 ln 命令一样。它主要做两件事:

    1. 创建一个目录项
    2. inode 结构体引用计数加 1。

    这两步是一个原子操作,要么全部失败,要么全部成功。

    #include 
    int link(const char *oldpath, const char *newpath);
    	
    	参数: 
     		oldpath: 原始文件名
    		newpath: 新的硬链接名
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    7、unlink函数

    删除一个名字(某些情况下删除这个名字所指向的文件)

    	#include
    
    	int unlink(const char* pathname);
    	
    	返回值:调用成功返回0,不成功返回-1.
    
    • 1
    • 2
    • 3
    • 4
    • 5

    删除时

    • 如果这个名字是指向这个文件的最后一个链接,并且没有进程处于打开这个文件的状态,则删除这个文件,释放这个文件占用的空间。
    • 如果这个名字是指向这个文件的最后一个链接,但有某个进程处于打开这个文件的状态,则暂时不删除这个文件,要等到打开这个文件的进程关闭这个文件的文件描述符后才删除这个文件。
    • 如果这个名字指向一个符号链接,则删除这个符号链接。
    • 如果这个名字指向一个socket、fifo或者一个设备,则这个socket、fifo、设备的名字被删除,当时打开这些socke、fifo、设备的进程仍然可以使用它们。
    unlink的特征

    清除文件时,如果文件的硬链接数到0了,没有dentry对应,但该文件仍不会马上被释放。要等到所有打开该文件的进程关闭该文件,系统才会挑时间将该文件释放掉。

    unlink的用途

    运行一个程序时有时需要创建一些临时文件。如果进程运行过程中突然终止了,而临时文件还没来的及删除,那么就会遗留下很多没用的临时文件,unlink提供了解决这个问题的一种方法。创建一个临时文件后一刻调用unlink删除文件。但是进程还是打开该文件的,所以该临时文件内容依旧是能被访问读和写的。但是进程终止后,该文件内容就会被删除。 ·

    8、readlink

    读取符号链接文件本身的内容,得到链接所指向的文件名。
    ssize_t readlink(const char *path,char *buf,size_t bufsiz);成功返回实际读到的字节数,失败返回-1,设置errno为相应值。
    也可以在bash上输入,比如readlink t.soft 会显示这个硬链接执行的位置

    9、rename函数

    重命名一个文件

    int rename(const char *oldpath,const char *newpath);
    
    • 1

    成功:0,失败:-1,设置errno为相应值。

    10、隐式回收

    当进程结束运行时,所有该进程打开的文件会被关闭,申请的内存空间会被释放。系统的这一特性称之为隐式回收系统资源。·因此在程序中打开了fd但是没有回收,在程序退出后会进行隐式回收。但不能依赖这个特性。

  • 相关阅读:
    ECMAScript 6 新特性详解
    JS递归函数详解
    【STM32 IIC通信与温湿度传感器AHT20(I2C_AHT20)】
    OpenGL调用窗口,方向键和鼠标
    11.24Spring学习第四天
    HuggingFace-利用BERT预训练模型实现中文情感分类(下游任务)
    基于spring boot 的学生科研项目共享平台毕业设计源码271611
    【Pytorch Lighting】第 6 章:深度生成模型
    Vue.js快速入门:构建现代Web应用
    技术干货 | 基于 MindSpore 实现图像分割之豪斯多夫距离
  • 原文地址:https://blog.csdn.net/baidu_41553551/article/details/126571098