美文网首页
文件和目录管理 - 文件和其元数据

文件和目录管理 - 文件和其元数据

作者: 无无吴 | 来源:发表于2019-08-26 09:48 被阅读0次

文件和其元数据(metadata)

linux中每个file对应一个inode,它不仅代表磁盘上的物理对象,也是内核中的一个概念实体,并且由一个数据结构体表示。


linux中查看inode的方式

The Stat Family

Unix提供了一系列函数,用于获取文件的元数据。

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

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

stat()返回由路径表示的文件的信息,而fstat()返回由文件描述符fd表示的文件的信息。lstat()与stat()相同, 除了在符号链接的情况下,lstat()返回有关链接本身的信息,而不是目标文件。

这些函数中的每一个都将信息存储在由用户提供的stat结构中。stat结构体定义在<bits/stat.h> 而这个由<sys/stat.h>包含。

struct stat{
        dev_t st_dev; /* ID of device containing file */
        ino_t st_ino; /* inode number */
        mode_t st_mode; /* permissions */
        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 blocks allocated */
        time_t st_atime; /* last access time */
        time_t st_mtime; /* last modification time */
        time_t st_ctime; /* last status change time */
};

成功返回0,失败返回-1并且设置errno。

//example retrive the size of a file provided on the command line:
int getFileSize(int argc, char*argv[]) {
    struct stat sb;
    int ret;
    if(argc < 2){
        fprintf(stderr, "usage: %s <file>\n", argv[0]);
        return 1;
    }

    ret = stat(argv[1], &sb);
    if(ret){
        perror("stat");
        return 1;
    }

    printf("%s is %ld bytes\n",
            argv[1], sb.st_size);

    return 0;
}

int main(int argc, char*argv[])
{
    getFileSize(argc, argv);
    return 0;
}

test result
//example for reporting file tyoe(such as symbolick link or block device node)
int getFileType(int argc, char **argv) {
    struct stat sb;
    int ret;
    if(argc < 2){
        fprintf(stderr, "usage: %s <file>\n", argv[0]);
        return 1;
    }
    ret = stat(argv[1], &sb);
    if(ret){
        perror("stat");
        return 1;
    }

    printf("File type: ");
    switch(sb.st_mode & S_IFMT){
        case S_IFBLK:
            printf("block device node\n");
            break;
        case S_IFCHR:
            printf("character device node\n");
            break;
        case S_IFDIR:
            printf("directory\n");
            break;
        case S_IFIFO:
            printf("FIFO\n");
            break;
        case S_IFLNK:
            printf("symbolic link\n");
            break;
        case S_IFREG:
            printf("regular file\n");
            break;
        case S_IFSOCK:
            printf("socket\n");
            break;
        default:
            printf("unknown\n");
            break;
    }
    return 0;
}

int main(int argc, char*argv[])
{
    getFileType(argc, argv);
    return 0;
}
test result
/*
 * is_on_physical_device - returns a positive
 * integer if 'fd' resides on a physical device,
 * 0 if the file resides on a nonphysical or
 * virtual device (e.g., on an NFS mount), and
 * −1 on error.
 */
int is_on_physical_device (int fd) {
        struct stat sb;
        int ret;
        ret = fstat (fd, &sb);
        if (ret) {
              perror ("fstat");
              return −1;
         }
         return gnu_dev_major (sb.st_dev);
}

Permissions

通过stat能获得file的权限,另外两个系统调用可以设置权限

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

int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);
//mode 参数
- S_IRWXU 所有者具有读取、写入和执行权限。
- S_IRUSR 所有这具有读取的权限
- S_IWUSR 所有者具有写入的权限
- S_IXUSR 所有者具有执行的权限
- S_IRWXG 组具有读取、写入和执行权限
- S_IRGRP 组具有读取的权限
- S_IWGRP 组具有写入的权限
- S_IXGRP 组具有执行的权限
- S_IRWXO 每个人都可以写入、读取和执行
- S_IROTH 每个人都可以读取
- S_IWOTH 每个人都可以写入
- S_IXOTH 每个人都可以执行

成功返回0,失败返回-1,并设置errno

//eample
int ret = chmod("./map.png", S_IRUSR | S_IWUSR);
if(ret)
        perror("chmod");
int ret = fchmod(fd, S_IRUSR|S_IWUSR);
if(ret)
        perror("fchmod");

Ownership

stat中st_uid和st_gid分别提供了文件的拥有者和组。下面这三个调用可以改变这两个值。

#include <sys/types.h>
#include <unistd.h>
int chown(const char*path, uid_t owner, gid_t group);
int lchown(const char*path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);

成功返回0,失败返回-1,并设置errno。
只有拥有CAP_CHOWN属性(通常是root进程)的进程才可以改变文件的owner。
如果owner和group参数值是-1的话,那么这个值将不被设置。

int ret;
/*
 * getgrnam() returns information on a group
 * given its name.
 */
gr = getgrnam ("officers");
if (!gr) {
/* likely an invalid group */
            perror ("getgrnam");
            return 1;
 }
/* set manifest.txt's group to 'officers' */
ret = chown("manifest.txt", -1, gr->gr_gid);
if (ret)
            perror ("chown");
/*
 * make_root_owner - changes the owner and group of the file
 * given by 'fd' to root. Returns 0 on success and −1 on
 * failure.
 */
int make_root_owner (int fd) {
int ret;
/* 0 is both the gid and the uid for root */
ret = fchown (fd, 0, 0);
if (ret)
      perror ("fchown");
      return ret;
 }

Extended Attributes

Linux 目前定义了四个扩展的属性命名空间,将来可能会定义更多。 目前的四个项目如下:

  • system
  • security
  • trusted
  • user

Extended Attribute Operations

POSIX定义了应用程序可以对给定文件的扩展属性执行的四个操作:

  • 给定一个文件,返回分配给扩展属性键的所有文件的列表。
  • 给定一个文件和一个键,返回相应的值。
  • 给定一个文件、一个键和一个值,将该值分配给键。
  • 给定一个文件和一个键,从文件中删除该扩展属性。
    对于每个操作,POSIX提供三个系统调用:
  • 在给定路径名上运行的版本;如果路径是指符号链接,则会在链接的实际目标上操作。
  • 在给定路径名上运行的版本;如果路径是指一个符号链接,则会在链接本身上操作。
  • 在文件描述符上操作的版本。

检索扩展属性

#include <sys/types.h>
#include <attr/xattr.h>
ssize_t getxattr (const char *path, const char *key,
void *value, size_t size);
ssize_t lgetxattr (const char *path, const char *key,
void *value, size_t size);
ssize_t fgetxattr (int fd, const char *key,
void *value, size_t size);

成功的调用将会把key相对应的值存储在buffer value中,size是buffer的size。
函数成功调用的话返回实际value对应的size。
如果size是零,函数会返回value的size,但不会存储金buffer value中。所以传0可以额让应用知道存储key的valued的buffer的实际大小。
失败返回-1并设置errno。

设置扩展属性

#include <sys/types.h>
#include <attr/xattr.h>
int setxattr (const char *path, const char *key,
                      const void *value, size_t size, int flags);
int lsetxattr (const char *path, const char *key,
                    const void *value, size_t size, int flags);
int fsetxattr (int fd, const char *key,
                    const void *value, size_t size, int flags);
  • 如果flag是XATTR_CREATE,如果扩展属性已经存在,则调用将失败。
  • 如果flag是XATTR_REPLACE,则如果扩展属性不存在,则调用将失败。
  • 默认行为是如果标志为0,则同时允许创建和替换两个行为。
  • 无论标志的值如何,除key以外的key将不受影响。
    成功返回0,失败返回-1。
#### 列出文件上的扩展属性
#include <sys/types.h>
#include <attr/xattr.h>
ssize_t listxattr (const char *path,
          char *list, size_t size);
ssize_t llistxattr (const char *path,
          char *list, size_t size);
ssize_t flistxattr (int fd,
          char *list, size_t size);
注解

如果size传入0的话,就可以知道实际buffer list需要的大小。
成功返回0,失败返回-1,并且设置errno。

移除一个扩展属性

#include <sys/types.h>
#include <attr/xattr.h>
int removexattr (const char *path, const char *key);
int lremovexattr (const char *path, const char *key);
int fremovexattr (int fd, const char *key);

成功返回0,失败返回-1。

相关文章

  • 文件和目录管理 - 文件和其元数据

    文件和其元数据(metadata) linux中每个file对应一个inode,它不仅代表磁盘上的物理对象,也是内...

  • linux基础(二)

    目录管理命令 mkdir,tree 文件的时间戳管理工具 touch stat filename 显示文件的元数据...

  • 文件和目录管理

    在复习Linux命令的时候,突然从百度发现了一个不错的网站,Linux命令大全 1.cd 主要用法:切换当前的工作...

  • 源码|HDFS之NameNode:创建目录

    namenode主要负责文件元信息的管理和文件到数据块的映射。其中,创建目录只涉及文件元信息的操作。本文分析nam...

  • Unix的文件管理(下)

    目录 access 函数 复制文件描述符 获取文件的元数据(或者叫做属性) 元数据中得到文件类型 元数据中得到文件...

  • ceph分布式存储-MDS介绍

    1. mds存储 元数据的内存缓存,为了加快元数据的访问。 保存了文件系统的元数据(对象里保存了子目录和子文件的名...

  • 第三章 基本的bash shell命令

    使用shell bash手册 浏览文件系统VFS 文件和目录 管理文件和目录 查看文件内容 3.1 启动shell...

  • linux基础2

    文件系统和磁盘管理 文件管理 查看文件信息: lsls是英文单词list的简写,其功能为列出目录的内容,是用户最常...

  • Linux的简单学习记录(三)

    Linux的文件目录管理一、文件和目录管理 1.cd命令与pwd命令 进入文件目录与现实当前文件目录 2.mkdi...

  • 利用元数据管理数据质量

    如何利用元数据管理数据质量:利用元数据管理数据质量 什么是元数据: 任何文件系统中的数据分为数据和元数据。数据是指...

网友评论

      本文标题:文件和目录管理 - 文件和其元数据

      本文链接:https://www.haomeiwen.com/subject/kdvlectx.html