Skip to content
Published at:

文件操作相关函数

stat/fstat/lstat函数:

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

获取文件状态信息;

区别:当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的信息。

struct stat结构体:

c
struct stat {
    dev_t           st_dev;         /* [XSI] ID of device containing file */ // 文件的设备编号
    ino_t           st_ino;         /* [XSI] File serial number */ // inode节点
    mode_t          st_mode;        /* [XSI] Mode of file (see below) */ // 文件的类型和存取的权限
    nlink_t         st_nlink;       /* [XSI] Number of hard links */
    uid_t           st_uid;         /* [XSI] User ID of the file */ // 用户ID
    gid_t           st_gid;         /* [XSI] Group ID of the file */ // 组ID
    dev_t           st_rdev;        /* [XSI] Device ID */
    struct  timespec st_atimespec;  /* time of last access */ // 最后一次访问时间
    struct  timespec st_mtimespec;  /* time of last data modification */ // 最后一次修改时间
    struct  timespec st_ctimespec;  /* time of last status change */ // 最后一次改变时间(指属性)
    off_t           st_size;        /* [XSI] file size, in bytes */ // 文件字节数(文件大小)
    blkcnt_t        st_blocks;      /* [XSI] blocks allocated for file */
    blksize_t       st_blksize;     /* [XSI] optimal blocksize for I/O */
    __uint32_t      st_flags;       /* user defined flags for file */
    __uint32_t      st_gen;         /* file generation number */
    __int32_t       st_lspare;      /* RESERVED: DO NOT USE! */
    __int64_t       st_qspare[2];   /* RESERVED: DO NOT USE! */
};

stat_demo.c

c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
    // int stat(const char *pathname, struct stat *buf);
    struct stat xixi;
    int ret = stat("xixi.txt", &xixi);
    int file_type = S_IFMT & xixi.st_mode;

    // file type
    printf(" file type ~~~~~~~~\n");
    switch (file_type) {
        {
        case S_IFIFO:
            printf("xixi is fifo file\n");
            break;
        case S_IFCHR:
            printf("xixi is char file\n");
            break;
        case S_IFDIR:
            printf("xixi is dir file\n");
            break;
        case S_IFBLK:
            printf("xixi is block file\n");
            break;
        case S_IFREG:
            printf("xixi is regular file\n");
            break;
        case S_IFLNK:
            printf("xixi is symbolic link file\n");
            break;
        case S_IFSOCK:
            printf("xixi is socket file\n");
            break;
        }
    }
    // 直接判断
    // S_ISBLK(xixi.st_mode) // 是否是块文件
    // S_ISCHR(xixi.st_mode) // 是否是字符文件
    // S_ISDIR(xixi.st_mode) // 是否是目录文件
    // S_ISFIFO(xixi.st_mode) // 是否是管道文件
    // S_ISREG(xixi.st_mode) // 是否是普通文件
    // S_ISLNK(xixi.st_mode) // 是否是链接文件
    // S_ISSOCK(xixi.st_mode) // 是否是socket文件

    // owner
    printf(" for owner ~~~~~~~~\n");
    int own_r = S_IRUSR & xixi.st_mode;
    if (own_r == S_IRUSR) {
        printf("owner has read permission\n");
    } else {
        printf("owner has not read permission\n");
    }
    int own_w = S_IWUSR & xixi.st_mode;
    if (own_w == S_IWUSR) {
        printf("owner has write permission\n");
    } else {
        printf("owner has not write permission\n");
    }
    int own_x = S_IXUSR & xixi.st_mode;
    if (own_x == S_IXUSR) {
        printf("owner has execute permission\n");
    } else {
        printf("owner has not execute permission\n");
    }

    // group
    printf(" for group ~~~~~~~~\n");
    int group_r = S_IRGRP & xixi.st_mode;
    if (group_r == S_IRGRP) {
        printf("group has read permission\n");
    } else {
        printf("group has not read permission\n");
    }
    int group_w = S_IWGRP & xixi.st_mode;
    if (group_w == S_IWGRP) {
        printf("group has write permission\n");
    } else {
        printf("group has not  write permission\n");
    }
    int group_x = S_IXGRP & xixi.st_mode;
    if (group_x == S_IXGRP) {
        printf("group has execute permission\n");
    } else {
        printf("group has not execute permission\n");
    }

    // other
    int other_r = S_IROTH & xixi.st_mode;
    if (other_r == S_IROTH) {
        printf("other has read permission\n");
    } else {
        printf("other has not read permission\n");
    }
    int other_w = S_IWOTH & xixi.st_mode;
    if (other_w == S_IWOTH) {
        printf("other has write permission\n");
    } else {
        printf("other has not  write permission\n");
    }
    int other_x = S_IXOTH & xixi.st_mode;
    if (other_x == S_IXOTH) {
        printf("other has execute permission\n");
    } else {
        printf("other has not execute permission\n");
    }

    printf("file size = %lld\n", xixi.st_size);

    return 0;
}

access函数:

  • int access(const char *pathname, int mode);

测试指定文件是否具有某种属性

  • R_OK:文件是否read权限
  • W_OK:文件是否有write权限
  • X_OK:文件是否有execute权限
  • F_OK:测试文件是否存在
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
    // file exists
    int ret = access("xixi.txt", F_OK);
    if (ret == 0) {
        printf("file exists\n");
    } else {
        printf("file does not exists\n");
    }

    // check read and write permission
    ret = access("xixi.txt", R_OK | W_OK);
    if (ret == 0) {
        printf("xixi.txt has read and write permission\n");
    } else {
        printf("xixi.txt has not read and write permission\n");
    }

    return 0;
}

chmod/chown函数:

修改mode和owner

  • int chmod(const char *pathname, mode_t mode);
  • int chown(const char *pathname, uid_t owner, gid_t group);

truncate/ftruncate函数:

  • int truncate(const char *path, off_t length); 通过路径名修改文件大小
  • int ftruncate(int fd, off_t length); 通过文件描述符修改文件大小
  • int link(const char *oldpath, const char *newpath); 创建一个硬链接
  • int symlink(const char *target, const char *linkpath); 创建一个软链接
  • ssize_t readlink(const char *pathname, char *buf, size_t bufsiz); 读软连接对应的文件名
  • int unlink(const char *pathname); 删除一个文件(软硬链接文件)

mkdir/mkdirat/rmdir函数:

  • int mkdir(const char *pathname, mode_t mode); 创建目录
  • int rmdir(const char *pathname); 删除目录

opendir/readdir/closedir函数

  • DIR *opendir(const char *name);
  • int readdir(unsigned int fd, struct old_linux_dirent *dirp, unsigned int count);
  • int closedir(DIR *dirp);

chdir/fchdir/getcwd函数:

  • int chdir(const char *path); 修改目录
  • int fchdir(int fd); 修改目录
  • char *getcwd(char *buf, size_t size); 获取当前工作目录