Bootstrap

Linux 目录和文件的库函数简介

在 Linux 系统编程中,我们经常需要对文件和目录进行各种操作,例如检查文件权限、获取文件信息、修改文件时间、重命名文件以及删除文件等。C 语言标准库和 Linux 系统提供了一系列相关的库函数,方便我们进行这些操作。下面将简单介绍

1. access() 库函数

access() 函数用于检查调用进程是否可以访问某个文件。

  • 包含头文件: #include <unistd.h>
  • 函数声明: int access(const char *pathname, int mode);
  • 参数说明:
    • pathname:要检查的文件路径名。
    • mode:要检查的访问权限,可以是以下值的组合:
      • R_OK:检查读权限。
      • W_OK:检查写权限。
      • X_OK:检查执行权限。
      • F_OK:检查文件是否存在。
  • 返回值: 成功返回 0,失败返回 -1,并设置 errno

代码示例:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>

int main() {
    char *filename = "test.txt";

    if (access(filename, F_OK) == 0) {
        printf("File %s exists.\n", filename);
        if (access(filename, R_OK) == 0) {
            printf("File %s has read access.\n", filename);
        } else {
            perror("Cannot read file");
        }
        if (access(filename, W_OK) == 0) {
            printf("File %s has write access.\n", filename);
        } else {
            perror("Cannot write file");
        }
        if (access(filename, X_OK) == 0) {
            printf("File %s has execute access.\n", filename);
        } else {
            perror("Cannot execute file");
        }
    } else {
        perror("File does not exist");
    }

    return 0;
}

2. stat() 库函数

stat() 函数用于获取文件的各种状态信息。

  • 包含头文件: #include <sys/stat.h>
  • 函数声明: int stat(const char *path, struct stat *buf);
  • 参数说明:
    • path:文件路径名。
    • buf:指向 struct stat 结构体的指针,用于存储文件信息。
  • 返回值: 成功返回 0,失败返回 -1,并设置 errno
2.1 struct stat 结构体

struct stat 结构体定义如下(部分重要成员):

struct stat {
    dev_t st_dev;      // 文件的设备编号
    ino_t st_ino;      // 文件的 inode 号
    mode_t st_mode;     // 文件的类型和权限
    nlink_t st_nlink;    // 文件的硬链接数
    uid_t st_uid;      // 文件所有者的用户 ID
    gid_t st_gid;      // 文件所有者的组 ID
    off_t st_size;     // 文件大小(字节)
    time_t st_atime;    // 最后访问时间
    time_t st_mtime;    // 最后修改时间
    time_t st_ctime;    // 最后状态更改时间
};

其中,st_mode 成员包含了文件类型和权限信息,可以使用以下宏进行判断:

  • S_ISREG(m):是否为普通文件。
  • S_ISDIR(m):是否为目录。
  • S_ISCHR(m):是否为字符设备。
  • S_ISBLK(m):是否为块设备。
  • S_ISFIFO(m):是否为 FIFO(命名管道)。
  • S_ISLNK(m):是否为符号链接。
  • S_ISSOCK(m):是否为套接字。

代码示例:

#include <stdio.h>
#include <sys/stat.h>
#include <time.h>

int main() {
    struct stat file_stat;
    if (stat("test.txt", &file_stat) == 0) {
        printf("File size: %ld bytes\n", file_stat.st_size);
        printf("Last modification time: %s", ctime(&file_stat.st_mtime));
        if (S_ISREG(file_stat.st_mode)) {
            printf("It is a regular file.\n");
        } else if (S_ISDIR(file_stat.st_mode)) {
            printf("It is a directory.\n");
        }
    } else {
        perror("stat");
    }
    return 0;
}

3. utime() 库函数

utime() 函数用于修改文件的访问时间和修改时间。

  • 包含头文件: #include <utime.h>
  • 函数声明: int utime(const char *filename, const struct utimbuf *times);
  • 参数说明:
    • filename:文件名。
    • times:指向 struct utimbuf 结构体的指针,如果为 NULL,则将文件的访问时间和修改时间设置为当前时间。

struct utimbuf 结构体定义如下:

struct utimbuf {
    time_t actime;  // 访问时间
    time_t modtime; // 修改时间
};
  • 返回值: 成功返回 0,失败返回 -1,并设置 errno

代码示例:

#include <stdio.h>
#include <utime.h>
#include <time.h>

int main() {
    struct utimbuf times;
    times.actime = time(NULL) - 3600; // 设置访问时间为一小时前
    times.modtime = time(NULL);     // 设置修改时间为当前时间

    if (utime("test.txt", &times) == 0) {
        printf("File times updated.\n");
    } else {
        perror("utime");
    }
    return 0;
}

4. rename() 库函数

rename() 函数用于重命名文件或目录。

  • 包含头文件: #include <stdio.h>
  • 函数声明: int rename(const char *oldpath, const char *newpath);
  • 参数说明:
    • oldpath:旧的文件或目录名。
    • newpath:新的文件或目录名。
  • 返回值: 成功返回 0,失败返回 -1,并设置 errno

代码示例:

#include <stdio.h>

int main() {
    if (rename("old_file.txt", "new_file.txt") == 0) {
        printf("File renamed successfully.\n");
    } else {
        perror("rename");
    }
    return 0;
}

5. remove() 库函数

remove() 函数用于删除文件或空目录。

  • 包含头文件: #include <stdio.h>
  • 函数声明: int remove(const char *pathname);
  • 参数说明: pathname:要删除的文件或目录名。
  • 返回值: 成功返回 0,失败返回 -1,并设置 errno

代码示例:

#include <stdio.h>

int main() {
    if (remove("file_to_delete.txt") == 0) {
        printf("File deleted successfully.\n");
    } else {
        perror("remove");
    }
    return 0;
}

扩展知识

  • 错误处理: 上述函数在失败时都会设置 errno,可以使用 perror() 函数或 strerror() 函数输出错误信息。
  • 权限掩码: 创建文件或目录时,可以使用 umask() 函数设置权限掩码,控制默认权限。
  • 目录操作: 除了上述函数,还有 mkdir()(创建目录)、rmdir()(删除空目录)、chdir()(改变当前工作目录)等函数用于目录操作。
;