• 2.文件系统


    一.stat()&fstat()&lstat()

    获取文件详细信息(文件大小,硬链接个数,ino编号,文件最近访问和修改时间,文件权限,文件类型,文件所有者ID和组ID)

    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main(int argc, char *argv[])
    {
    
        
        struct stat sb;
        
        if (argc != 2) {
            fprintf(stderr, "Usage: %s <pathname>
    ", argv[0]);
            exit(EXIT_FAILURE);
        }
            
        if (stat(argv[1], &sb) == -1) {
            perror("stat");
            exit(EXIT_FAILURE);
        }
    
        printf("File type:            ");
        switch (sb.st_mode & S_IFMT) {
            case S_IFBLK:    printf("block device
    ");    break;
            case S_IFCHR:    printf("character device
    ");    break;
            case S_IFDIR:    printf("directory
    ");        break;
            case S_IFIFO:    printf("FIFO/pipe
    ");        break;
            case S_IFLNK:    printf("symlink
    ");         break;
            case S_IFREG:    printf("regular file
    ");    break;
            case S_IFSOCK:    printf("socket
    ");        break;
            default:    printf("unknow?
    ");        break;
        }    
        
        printf("I-node number:            %ld
    ", (long)sb.st_ino);
        printf("Mode:                %lo (octal)
    ", 
            (unsigned long)sb.st_mode);
        printf("Link count:            %ld
    ", (long)sb.st_nlink);
        printf("Ownership:            UID=%ld    GID=%ld
    ", 
            (long)sb.st_uid, (long)sb.st_gid);
        printf("Preferred I/O block size:    %ld bytes
    ", 
            (long)sb.st_blksize);
        printf("File size:            %lld bytes
    ", 
            (long long)sb.st_size);
        printf("Blocks allocated:        %lld
    ", 
            (long long)sb.st_blocks);
        printf("Last status change:        %s", ctime(&sb.st_ctime));
        printf("Last file access:        %s", ctime(&sb.st_atime));
        printf("Last file modification:        %s", ctime(&sb.st_mtime));
    
        exit(EXIT_SUCCESS);
    }

    运行结果:

    yongdaimi@ubuntu:~/Documents/linux-sys/02-文件系统$ ./app empty.txt
    File type: regular file
    I-node number: 1101565
    Mode: 100664 (octal)
    Link count: 1
    Ownership: UID=1000 GID=1000
    Preferred I/O block size: 4096 bytes
    File size: 9 bytes
    Blocks allocated: 8
    Last status change: Thu Feb 1 19:14:03 2018
    Last file access: Thu Feb 1 22:26:46 2018
    Last file modification: Thu Feb 1 19:14:03 2018

    二.access()

    检测文件是否存在,是否具有读写和执行权限

    #include <unistd.h>
    #include <stdio.h>
    
    int main()
    {
        
        if (access("test.txt", F_OK|X_OK) < 0) {
            printf("FILE Not Exists or No Execute permission
    ");
        } else {
            printf("FILE Exists
    ");
        }
        
        return 0;
    }

    三.chmod()&fchmod()

    修改文件访问权限

    #include <sys/stat.h>
    #include <sys/types.h>
    #include <fcntl.h>
    #include <stdio.h>
    
    int main()
    {
        
        int fd;
        if ((fd = open("empty.txt", O_RDWR)) < 0) {
            perror("open");
        }
    
        fchmod(fd, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP);
        close(fd);
        return 0;
    }

    四.truncate()&ftruncate()

    该函数用于将文件截取为指定的长度,若要设置文件长度为0,可将第二个参数置为0

    也可以使用open函数的O_TRUNC 标志来将文件长度截取为0

    #include <unistd.h>
    #include <sys/types.h>
    #include <stdio.h>
    
    
    
    int main()
    {
        int ret;
        ret = truncate("empty.txt", 0);
        
        if (ret < 0)  {
            perror("truncate");
        }
    
        return 0;
    }

    运行结果:

    yongdaimi@ubuntu: stat empty.txt

    File: ‘empty.txt’
    Size: 0 Blocks: 0 IO Block: 4096 regular empty file
    Device: 801h/2049d Inode: 1103086 Links: 1
    Access: (0740/-rwxr-----) Uid: ( 1000/yongdaimi) Gid: ( 1000/yongdaimi)
    Access: 2018-02-05 17:10:07.617000418 -0800
    Modify: 2018-02-05 17:09:49.485000637 -0800
    Change: 2018-02-05 17:09:49.485000637 -0800
    Birth: -

    五.link()&symlink()&readlink()&unlink()

    ◆link()

    #include <unistd.h>
    int link(const char *oldpath, const char *newpath);

    创建一个硬链接。

    当rm删除文件时,只是删除了目录下的记录项和把inode硬链接计数减1,当硬链接计数减为0时,当会真正删除文件。

    * 硬链接通常要求位于同一文件系统中,POSIX允许夸文件系统
    * 符号链接没有文件系统限制
    * 通常不允许创建目录的硬链接,某些unix系统下超级用户可以创建目录的硬链
    * 创建目录项以及增加硬链接计数应当是一个原子操作

    ◆symlink()

    #include <unistd.h>
    int symlink(const char *oldpath, const char *newpath)

    建立文件符号链接。

    ◆readlink()

    #include <unistd.h>
    ssize_t readlink(const char *path, char *buf, size_t bufsiz)

    读符号链接所指向的文件名字不读文件内容。例如符号链接指向的文件名为“new.txt”, 则buf则存储的内容就为new.txt

    ◆unlink()

    #include <unistd.h>
    int unlink(const char *pathname)
    1. 如果是符号链接,删除符号链接
    2. 如果是硬链接,硬链接数减1,当减为0时,释放数据块和inode
    3. 如果文件硬链接数为0,但有进程已打开该文件,并持有文件描述符,则等该进程关闭该文件时,kernel才真正去删除该文件
    4. 利用该特性创建临时文件,先open或creat创建一个文件,马上unlink此文件
    #include <unistd.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    #include <stdlib.h>
    
    
    static const char *str = "www.baidu.com";
    static const char *filename = "201321321313131313131313131313131.tmp";
    
    
    int main()
    {
        
        int fd;
        if ((fd = open(filename, O_CREAT|O_RDWR, 0777)) < 0) {
            perror("open");
            exit(1);
        }
        
        int ret = write(fd, str, strlen(str));
        if (ret < 0) {
            perror("write");
            exit(1);
        }
        
        sleep(30);
        close(fd);
        unlink(filename);
        return 0;
    }

    当进程退出后,临时文件也会相应删除。

    六.rename()&chdir()&getcwd()&pathconf()

    ◆rename()

    重命名文件

    #include <stdio.h>
    int rename(const char *oldpath, const char *newpath);

    ◆chdir()&getcwd

    #include <unistd.h>
    int chdir(const char *path);
    int fchdir(int fd);

    chdir()改变当前进程工作目录,类似于cd命令; getcwd()获取当前进程工作目录,类似于pwd指令

    #include <unistd.h>
    char *getcwd(char *buf, size_t size);

    例:

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    
    
    
    int main()
    {
        
        char buf[4096] = {0};    
        
        int ret = chdir("/home/yongdaimi/ABC");
        if (ret < 0) {
            perror("chdir");
            exit(1);
        }
    
        char *pathname = getcwd(buf, sizeof(buf));    
        if (pathname != NULL) {
            printf("current working DIR is: %s
    ", pathname);
        } else {
            perror("getcwd");
            exit(1);
        }    
    
        if (access("apple.txt", F_OK) < 0) {
            printf("FILE not found
    ");    
        } else {
            printf("FILE has found
    ");
        }
        return 0;
    }

    运行结果:

    current working DIR is: /home/yongdaimi/ABC
    FILE has found

    ◆pathconf()&fpathconf()

    #include <unistd.h>
    long fpathconf(int fd, int name);
    long pathconf(char *path, int name);

    测试系统资源限制,可籍于此函数获得:

    _PC_NAME_MAX 返回一个文件名的最大长度(linux下文件名的最大长度是255个字节)
    _PC_LINK_MAX 最大硬链接数
    _PC_PATH_MAX 最大路径长度
    _PC_PIPE_BUF 最大管道的缓冲区

    例:

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    
    
    int main()
    {    
        
        long ret = pathconf("google.txt", _PC_NAME_MAX);
        if (ret < 0) {
            perror("ret");
            exit(1);
        } else {
            printf("cur value is: %ld
    ", ret);
        }
        return 0;
    }

    运行结果:

    cur value is: 255

    七.mkdir()&rmdir()&opendir()&fdopendir()&closedir()

    ◆mkdir()

    创建一个目录,类似于mkdir指令

    #include <sys/stat.h>
    #include <sys/types.h>
    int mkdir(const char *pathname, mode_t mode);

    ◆rmdir()

    删除目录,类似于rmdir指令

    #include <unistd.h>
    int rmdir(const char *pathname);

    ◆opendir()&fdopendir

    打开目录

    #include <sys/types.h>
    #include <dirent.h>
    DIR *opendir(const char *name);
    DIR *fdopendir(int fd);

    ◆closedir()

    关闭目录

    #include <sys/types.h>
    #include <dirent.h>
    int closedir(DIR *dirp);

    八.readdir()&rewinddir()&telldir()&seekdir()

    ◆readdir()

    readdir每次返回一条记录项,DIR*指针指向下一条记录项

    #include <dirent.h>
    struct dirent *readdir(DIR *dirp);
    
    struct dirent {
        ino_t d_ino; /* inode number */
        off_t d_off; /* offset to the next dirent */
        unsigned short d_reclen; /* length of this record */
        unsigned char d_type; /* type of file; not supported by all file system types */
        char d_name[256]; /* filename */
    };

    例:

    #include <sys/types.h>
    #include <dirent.h>
    #include <stdio.h>
    #include <sys/stat.h>
    
    
    
    static void printFileType(int fileType)
    {
        printf("current fileType is: %d
    ", fileType);
        switch (fileType) {
            case DT_BLK:    printf("File-type: block device
    ");    break;
            case DT_CHR:    printf("File-type: character device
    ");break;
            case DT_DIR:    printf("File-type: directory
    ");    break;
            case DT_FIFO:    printf("File-type: FIFO/pipe
    ");    break;
            case DT_LNK:     printf("File-type: symlink
    ");        break;
            case DT_REG:     printf("File-type: regular file
    ");    break;
            case DT_SOCK:    printf("File-type: socket
    ");        break;
            default:    printf("File-type: unknow?
    ");        break;
        }
        
    }
    
    
    int main()
    {
        
        const char *filePath = "ndk";
        DIR *directory = opendir(filePath);    
        struct dirent *p;    
        
        while ((p = readdir(directory)) != NULL) {
            char *name = p->d_name;        
            if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) continue;        
            printf("File-ino: %ld
    ", p->d_ino);
            printf("File-off: %ld
    ", p->d_off);
            printf("File-reclen: %u
    ", p->d_reclen);
            printFileType(p->d_type);
            printf("File-name: %s
    ", name);
            printf("------------------------------------------
    ");
        }
        closedir(directory);        
        return 0;
    }

    运行结果:

    File-ino: 1122632
    File-off: 572686190995098447
    File-reclen: 24
    current fileType is: 4
    File-type: directory
    File-name: obj
    ------------------------------------------
    File-ino: 1122643
    File-off: 3303630722307380472
    File-reclen: 24
    current fileType is: 4
    File-type: directory
    File-name: libs
    ------------------------------------------
    File-ino: 1122647
    File-off: 9223372036854775807
    File-reclen: 24
    current fileType is: 4
    File-type: directory
    File-name: jni
    ------------------------------------------

    ◆rewinddir()

    移动目录指针到起始位置

    #include <sys/types.h>
    #include <dirent.h>
    void rewinddir(DIR *dirp);

    ◆telldir()&seekdir()

    telldir() 返回目录指针当前在什么位置

    seekdir() 移动目录指针到什么位置

    #include <dirent.h>
    long telldir(DIR *dirp);
    #include
    <dirent.h> void seekdir(DIR *dirp, long offset);

    例:

    #include <sys/types.h>
    #include <dirent.h>
    #include <stdio.h>
    #include <sys/stat.h>
    
    
    
    static void printFileType(int fileType)
    {
        printf("current fileType is: %d
    ", fileType);
        switch (fileType) {
            case DT_BLK:    printf("File-type: block device
    ");    break;
            case DT_CHR:    printf("File-type: character device
    ");break;
            case DT_DIR:    printf("File-type: directory
    ");    break;
            case DT_FIFO:    printf("File-type: FIFO/pipe
    ");    break;
            case DT_LNK:     printf("File-type: symlink
    ");        break;
            case DT_REG:     printf("File-type: regular file
    ");    break;
            case DT_SOCK:    printf("File-type: socket
    ");        break;
            default:    printf("File-type: unknow?
    ");        break;
        }
        
    }
    
    
    int main()
    {
        
        const char *filePath = "ndk";
        DIR *directory = opendir(filePath);    
        struct dirent *p;    
        long dir_pos;
        
        while ((p = readdir(directory)) != NULL) {
            char *name = p->d_name;        
            if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) continue;        
            if (strcmp(name, "obj") == 0) {
                // record current dir point's position.
                dir_pos = telldir(directory);    
            }
            printf("File-ino: %ld
    ", p->d_ino);
            printf("File-off: %ld
    ", p->d_off);
            printf("File-reclen: %u
    ", p->d_reclen);
            printFileType(p->d_type);
            printf("File-name: %s
    ", name);
            printf("------------------------------------------
    ");
        }
        
        // Move dir pointer position to "obj"    
        seekdir(directory, dir_pos);
        while ((p = readdir(directory)) != NULL) {
            char *name = p->d_name;        
            if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) continue;        
            if (strcmp(name, "obj") == 0) {
                dir_pos = telldir(directory);    
            }
            printf("File-ino: %ld
    ", p->d_ino);
            printf("File-off: %ld
    ", p->d_off);
            printf("File-reclen: %u
    ", p->d_reclen);
            printFileType(p->d_type);
            printf("File-name: %s
    ", name);
            printf("------------------------------------------
    ");
        }
    
        closedir(directory);        
        return 0;
    }

    运行结果:

    File-ino: 1122632
    File-off: 572686190995098447
    File-reclen: 24
    current fileType is: 4
    File-type: directory
    File-name: obj
    ------------------------------------------
    File-ino: 1122643
    File-off: 3303630722307380472
    File-reclen: 24
    current fileType is: 4
    File-type: directory
    File-name: libs
    ------------------------------------------
    File-ino: 1122647
    File-off: 9223372036854775807
    File-reclen: 24
    current fileType is: 4
    File-type: directory
    File-name: jni
    ------------------------------------------
    File-ino: 1122643
    File-off: 3303630722307380472
    File-reclen: 24
    current fileType is: 4
    File-type: directory
    File-name: libs
    ------------------------------------------
    File-ino: 1122647
    File-off: 9223372036854775807
    File-reclen: 24
    current fileType is: 4
    File-type: directory
    File-name: jni
    ------------------------------------------

  • 相关阅读:
    Python 多线程、进程
    Python网络编程 Socket编程
    Python基础7 面向对象编程进阶
    Python基础6 面向对象编程
    Python基础5 常用模块学习
    Python基础4 迭代器、装饰器、软件开发规范
    Python基础3 函数、递归、内置函数
    Python基础2 列表 字典 集合
    21-Python-多进程
    20-Python-queue队列
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/7806130.html
Copyright © 2020-2023  润新知