• Linux System Programming 学习笔记(八) 文件和目录管理


    1. 文件和元数据

    每个文件都是通过inode引用,每个inode索引节点都具有文件系统中唯一的inode number
    一个inode索引节点是存储在Linux文件系统的磁盘介质上的物理对象,也是LInux内核通过数据结构表示的实体
    inode存储相关联文件的元数据
     
    ls -i 命令获取文件的inode number
     
    /* obtaining the metadata of a file */
    #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);

    注意:lstat函数可以获取 符号链接的文件元数据,lstat() returns information about the link itself and not the target file

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

    2. 目录

    a directory contains a list of filenames, each of which maps to an inode number. Each name is called a directory entry, and each name-to-inode mapping is called a link
    当打开给定目录中的文件,内核查询相应的inode编号,然后将inode编号传递给文件系统,文件系统使用inode编号来寻找相应的存储在物理介质中的文件
     
    Reading a Directory’s Contents : 
    /* creates a directory stream representing the directory given by name */
    #include <sys/types.h>
    #include <dirent.h>
    DIR * opendir (const char *name);
    /* returns the next entry in the directory represented by dir */
    #include <sys/types.h>
    #include <dirent.h>
    struct dirent * readdir (DIR *dir);
    /* closes the directory stream represented by dir */
    #include <sys/types.h>
    #include <dirent.h>
    int closedir (DIR *dir);
    /*
     * find_file_in_dir - searches the directory 'path' for a
     * file named 'file'.
     *
     * Returns 0 if 'file' exists in 'path' and a nonzero
     * value otherwise.
     */
    int find_file_in_dir (const char *path, const char *file)
    {
            struct dirent *entry;
            int ret = 1;
            DIR *dir;
            dir = opendir (path);
            errno = 0;
            while ((entry = readdir (dir)) != NULL) {
                    if (strcmp(entry->d_name, file) == 0) {
                            ret = 0;
                            break;
                    }
            }
            if (errno && !entry)
                    perror ("readdir");
            closedir (dir);
            return ret;
    }

    3. 链接

    each name-to-inode mapping in a directory is called a link.
    Most files have a link count of 1,that is, they are pointed at by a single directory entry
    当一个文件的链接计数减为0时,文件被标记为free,如果存在进程仍在使用此文件,则该文件将保留在文件系统中
     
    Linux内核使用 a link count and a usage count 实现,一个文件只有其link count和usage count都为0时,才会从文件系统移除
     
    硬链接:
    /* creates a new link under the path newpath for the existing file oldpath */
    #include <unistd.h>
    int link (const char *oldpath, const char *newpath);
    成功调用之后,oldpath and newpath refer to the same file
     
    符号链接(软链接):
    软链接可以跨文件系统,链接到任何文件
    /* creates the symbolic link newpath pointing at the target oldpath */
    #include <unistd.h>
    int symlink (const char *oldpath, const char *newpath);

    解链:

    #include <unistd.h>
    int unlink (const char *pathname);
    Once no process has the file open, it is deleted
     

    4. Copying and Moving Files

     
    Unix没有提供可以直接复制文件和目录的系统调用
     
     copying a file src to a file named dst:
    1). Open src.
    2). Open dst, creating it if it does not exist, and truncating it to zero length if it does exist.
    3). Read a chunk of src into memory.
    4). Write the chunk to dst.
    5). Continue until all of src has been read and written to dst.
    6). Close dst.
    7). Close src.
     

    5. 块设备

    The null device lives at /dev/null. The kernel silently discards all write requests to the device. All read requests to the file return end-of-file (EOF).
    The zero device lives at /dev/zero.  读此设备返回null字符,写此设备被丢弃
    The full device lives at /dev/full.  读此设备返回null字符,写此设备将触发错误表示设备已满
    The kernel's random number generators live at /dev/random. 
  • 相关阅读:
    使用offerShow小程序查询程序员薪水
    StoryBoard中使用segue传值
    在Xcode11中添加launchImage
    OC之打乱对象数组
    HDU Today
    洛谷:P1048 采药
    洛谷:P1928 外星密码
    洛谷:P1757 通天之分组背包
    洛谷:P1115 最大子段和
    洛谷:P1104 生日
  • 原文地址:https://www.cnblogs.com/wwwjieo0/p/3756033.html
Copyright © 2020-2023  润新知