APUE 文件、目录、硬链接软链接等

(一)文件的状态

主要通过stat函数获取文件状态,文件通过pathname获取,而返回的信息通过一个struct stat*得到,

int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);

区别在与Path给出了文件的目录,Fd表示已经打开的文件。

该结构体如下:

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 filesystem 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 */
};

常用的st_mode,以前知道可以获取到文件的访问权限,其实,该成员还能获取文件的类型:
比如有普通文件、目录文件等等。

S_IFMT     0170000  // bit mask for the file type bit fields
S_IFSOCK   0140000  // socket
S_IFLNK    0120000  // symbolic link
S_IFREG    0100000  // regular file
S_IFBLK    0060000  // block device
S_IFDIR    0040000  // directory
S_IFCHR    0020000  // character device
S_IFIFO    0010000  // FIFO
S_ISUID    0004000  // set-user-ID bit
S_ISGID    0002000  // set-group-ID bit (see below)
S_ISVTX    0001000  // sticky bit (see below)
S_IRWXU    00700    // mask for file owner permissions
S_IRUSR    00400    // owner has read permission
S_IWUSR    00200    // owner has write permission
S_IXUSR    00100    // owner has execute permission
S_IRWXG    00070    // mask for group permissions
S_IRGRP    00040    // group has read permission
S_IWGRP    00020    // group has write permission
S_IXGRP    00010    // group has execute permission
S_IRWXO    00007    // mask for permissions for others (not in group)
S_IROTH    00004    // others have read permission
S_IWOTH    00002    // others have write permission
S_IXOTH    00001    // others have execute permission

对于文件权限,可以使用S_IRGRP|S_IROTH|S_IRUSR|S_IWUSR,也可以使用八进制如0644

一个示例

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

    int main(int argc, char *argv[])
{
    const char * const PATHNAME = "/home/zhangxiao/zxtest/pipe/myfifo";//关联的路径名
    struct stat sb1;
    struct stat sb;



    int fd= socket(AF_INET,SOCK_STREAM,0);
    assert(fd>0);
    if (fstat(fd, &sb) == -1) {
    perror("stat");
    exit(EXIT_FAILURE);
    }
  if (stat(PATHNAME, &sb1) == -1) {
    perror("stat");
    exit(EXIT_FAILURE);
    }

    printf("fd1 File type:                ");
    switch (sb.st_mode & S_IFMT) {
    case S_IFBLK:  printf("block device\n");            break;
    case S_IFCHR:  printf("character device\n");        break;
    case S_IFDIR:  printf("directory\n");               break;
    case S_IFIFO:  printf("FIFO/pipe\n");               break;
    case S_IFLNK:  printf("symlink\n");                 break;
    case S_IFREG:  printf("regular file\n");            break;
    case S_IFSOCK: printf("socket\n");                  break;
    default:       printf("unknown?\n");                break;
    }
    printf("fd2 File type:                ");
    switch (sb1.st_mode & S_IFMT) {
    case S_IFBLK:  printf("block device\n");            break;
    case S_IFCHR:  printf("character device\n");        break;
    case S_IFDIR:  printf("directory\n");               break;
    case S_IFIFO:  printf("FIFO/pipe\n");               break;
    case S_IFLNK:  printf("symlink\n");                 break;
    case S_IFREG:  printf("regular file\n");            break;
    case S_IFSOCK: printf("socket\n");                  break;
    default:       printf("unknown?\n");                break;
    }

    return 0;

}

结果如下:
这里写图片描述


(二)文件系统

几个关键的概念,inode节点,链接计数,硬链接,符号链接(软链接)等

操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个”块”(block)。这种由多个扇区组成的”块”,是文件存取的最小单位。”块”的大小,最常见的是4KB,即连续八个 sector组成一个 block。

文件数据都储存在”块”中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为”索引节点”。

inode包含文件的元信息:

 * 文件的字节数
 * 文件拥有者的User ID
 * 文件的Group ID
 * 文件的读、写、执行权限
 * 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
 * 链接数,即有多少文件名指向这个inode
 * 文件数据block的位置

除了文件的存储位置以外,其他的属性与stat返回的结果类似。

(1)普通文件

而同一个inode节点可能有多个指向他的目录项,这就增加了其链接计数,这就是所谓的硬链接,其工作原理有点像shared_ptr

PS:目录块中的目录项,包括inode节点编号和文件名。

另外一种链接叫做软链接也叫符号链接,符号链接文件的实际内容,包含了该符号链接所指向的文件的名字,符号链接就像是普通指针,保存对象的地址。
因此,软链接不能脱离他链接的对象而存在。

(2)目录

对于一个empty目录来说,他的链接计数至少为2,这个数字的怎么来的呢?
首先,对于任何一个空的文件夹来说,他至少包含./../,其中一个链接计数来自于此,
另外,命名该目录(例如empty)的目录项也会为链接计数贡献一点。

如果一个目录中至少包含一个目录,那么他的链接技术至少为3,其实也很好理解,除了上述的2以外,在其子目录中的../目录项也会为其链接计数贡献一点。

(3)硬链接和软链接设置与查看

现在知道了概念, 那么怎么设置和查看硬链接和软链接?

设置硬链接
ln a b
设置软链接
ln -s a b
查看硬链接

先通过ls -i找到inode节点号,再用find
这里写图片描述

查看软链接

直接ls -l
这里写图片描述

(三) 参考

1.APUE
2.Linux man

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值