linux系统编程(六) linux文件系统的操作(上)

简介: linux系统编程(六) linux文件系统的操作

一、文件系统操作


1.文件存储


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


1.1 inode


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

少量常用、近期使用的inode会被缓存到内存中。


1.2 dentry


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

1670994258061.jpg

1670994266903.jpg

1670994272976.jpg

dentry被删掉之后,inode还在,磁盘对应位置就不能被替换。说明文件并没有真正删除。

但是inode被删除以后,对应磁盘允许被替换,这样就会导致,文件真正可能被删除。


1.3 文件系统


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


2. 文件操作


2.1 stat函数


获取文件属性,(从inode结构体中获取)  
  int stat(const char *path, struct stat *buf);  成返回0;失败返回-1 设置errno为恰当值。
  参数1:文件名
  参数2:inode结构体指针 (传出参数)
文件属性将通过传出参数返回给调用者。
练习:使用stat函数查看文件属性            
【stat.c】
The stat structure
       All of these system calls return a stat structure, which contains the following fields:
           struct stat {
               dev_t     st_dev;         /* ID of device containing file */
               ino_t     st_ino;         /* Inode number */
               mode_t    st_mode;        /* File type and mode */
               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;     /* Block size for filesystem I/O */
               blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */
               /* Since Linux 2.6, the kernel supports nanosecond
                  precision for the following timestamp fields.
                  For the details before Linux 2.6, see NOTES. */
               struct timespec st_atim;  /* Time of last access */
               struct timespec st_mtim;  /* Time of last modification */
               struct timespec st_ctim;  /* Time of last status change */
           #define st_atime st_atim.tv_sec      /* Backward compatibility */
           #define st_mtime st_mtim.tv_sec
           #define st_ctime st_ctim.tv_sec
           };
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/stat.h>
int main(int argc,char *argv[])
{
        struct stat sbuf;
        int ret =stat(argv[1],&sbuf);
        if(ret == -1){
                perror("stat error");
                exit(1);
        }
        printf("file size :%ld\n",sbuf.st_size);
        return 0;
}


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:不会
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/stat.h>
int main(int argc,char *argv[])
{
        struct stat sbuf;
        int ret =lstat(argv[1],&sbuf);
        if(ret == -1){
                perror("stat error");
                exit(1);
        }
        if(S_ISREG(sbuf.st_mode)){
                printf("it's a regular\n");
        }else if(S_ISDIR(sbuf.st_mode)){
                printf("it's a dir\n");
        }else if(S_ISFIFO(sbuf.st_mode)){
                printf("it's a pipe");
        }else if(S_ISLNK(sbuf.st_mode)){
                printf("it's a sym link\n");
        }
        return 0;
}


2.3 特殊权限位


1670994361523.jpg

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


2.3.1 黏住位


早起计算机内存紧,只有精要的常用的程序可以常驻物理内存,剩下的要暂存磁盘中。当内存不够用的时候会将该部分程序存回磁盘,腾出内存空间。若文件设置了黏住位,那么即使在内存比较吃紧的情况下,也不会将该文件回存到磁盘上。由于现阶段操作系统的虚拟内存管理分页算法完善。该功能已经被废弃。
但我们仍然可以对目录设置黏住位。被设置了该位的目录,其内部文件只有:
①超级管理员
②该目录所有者
③该文件的所有者 
以上三种用户有权限做删除、修改操作。其他用户可以读、创建但不能随意删除。


2.3.2 setUID位

进程有两个ID:EID(有效用户ID),表示进程履行哪个用户的权限。
         UID(实际用户ID),表示进程实际属于哪个用户。
  多数情况下,EID和UID相同。但是,当文件的setID被设置后两个ID则有可能不一样。
  例如:当进程执行一个root用户的文件,若该文件的setID位被设置为1, 那么执行该文件时,进程的UID不变。EID变为root,表示进程开始履行root用户权限。

1670994385229.jpg


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);
相关文章
|
1天前
|
关系型数据库 MySQL Linux
Linux系统如何设置自启动服务在MySQL数据库启动后执行?
【10月更文挑战第25天】Linux系统如何设置自启动服务在MySQL数据库启动后执行?
22 3
|
1天前
|
Linux Shell
Linux系统
是对Linux系统进行管理的命令。对于Linux系统来说,无论是中央处理器、内存、磁盘驱动器、键盘、鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命令类似。linux命令在系统中有两种类型:内置Shell命令和Linux命令。
|
3天前
|
Linux Shell
Linux系统
是对Linux系统进行管理的命令。对于Linux系统来说,无论是中央处理器、内存、磁盘驱动器、键盘、鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命令类似。linux命令在系统中有两种类型:内置Shell命令和Linux命令。Linux系统
|
2天前
|
Linux Shell
Linux系统
是对Linux系统进行管理的命令。对于Linux系统来说,无论是中央处理器、内存、磁盘驱动器、键盘、鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命令类似。linux命令在系统中有两种类型:内置Shell命令和Linux命令。
|
2天前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
4天前
|
Linux Shell
Linux系统
是对Linux系统进行管理的命令。对于Linux系统来说,无论是中央处理器、内存、磁盘驱动器、键盘、鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命令类似。linux命令在系统中有两种类型:内置Shell命令和Linux命令。
|
4天前
|
存储 安全 关系型数据库
Linux系统在服务器领域的应用与优势###
本文深入探讨了Linux操作系统在服务器领域的广泛应用及其显著优势。通过分析其开源性、安全性、稳定性和高效性,揭示了为何Linux成为众多企业和开发者的首选服务器操作系统。文章还列举了Linux在服务器管理、性能优化和社区支持等方面的具体优势,为读者提供了全面而深入的理解。 ###
|
5月前
|
消息中间件 存储 缓存
【嵌入式软件工程师面经】Linux系统编程(线程进程)
【嵌入式软件工程师面经】Linux系统编程(线程进程)
122 1
|
6月前
|
Linux 调度 数据库
Linux下的系统编程——线程同步(十三)
Linux下的系统编程——线程同步(十三)
100 0
Linux下的系统编程——线程同步(十三)
|
存储 Linux 调度
Linux系统编程 多线程基础
Linux系统编程 多线程基础
60 1