常用文件操作函数【fcntl()、stat()、access()】

fcntl()函数

函数原型

#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* arg */ );

参数

  • fd:需要操作的文件描述符。
  • cmd:控制命令,用于指定对文件描述符执行的操作。
  • arg:可选参数,与具体命令相关,可能是一个整数值或指针。

返回值

  • 成功时,根据 cmd 的不同,返回不同的结果。
  • 失败时,返回 -1,并设置 errno

常用cmd命令

获取或设置文件描述符标志

  • F_GETFD:获取文件描述符的标志。
  • F_SETFD:设置文件描述符的标志。
    • 文件描述符标志目前只有一个:FD_CLOEXEC
    • FD_CLOEXEC
  • 如果设置了该标志,则当调用 exec 系列函数执行新程序时,文件描述符会被自动关闭。
int flags = fcntl(fd, F_GETFD);
if (flags == -1) {
    perror("fcntl F_GETFD");
}
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1) {
    perror("fcntl F_SETFD");
}

获取或设置文件状态标志

  • F_GETFL:获取文件状态标志。
  • F_SETFL:设置文件状态标志。
    • 文件状态标志包括:
      • O_NONBLOCK:非阻塞模式。
      • O_APPEND:追加模式(写入的数据会追加到文件末尾)。
  • 示例(设置非阻塞模式):
int flags = fcntl(fd, F_GETFL);
if (flags == -1) {
    perror("fcntl F_GETFL");
}
flags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) == -1) {
    perror("fcntl F_SETFL");
}

文件锁

  • F_GETLK:获取文件锁状态。
  • F_SETLK:设置文件锁(非阻塞模式)。
  • F_SETLKW:设置文件锁(阻塞模式)。
    • 文件锁类型:
      • F_RDLCK:共享锁(读锁)。
      • F_WRLCK:独占锁(写锁)。
      • F_UNLCK:解锁。
  • 示例(设置写锁):
struct flock fl;
fl.l_type = F_WRLCK; // 写锁
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0; // 锁定整个文件
if (fcntl(fd, F_SETLK, &fl) == -1) {
    perror("fcntl F_SETLK");
}

stat函数

功能:stat 是一个用于获取文件状态信息的系统调用函数,它能够返回指定文件的各种元数据,比如文件大小、权限、最后修改时间等。

函数原型

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

int stat(const char *pathname, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);
int fstat(int fd, struct stat *buf);
  • stat
    • 获取文件的元数据。
    • 如果路径是符号链接,则获取目标文件的元数据。
  • lstat
    • 类似于 stat,但如果路径是符号链接,它会返回链接本身的元数据。
  • fstat
    • 获取通过文件描述符表示的文件的元数据。

struct stat 结构体

文件类型与访问权限

st_mode 包含文件的类型和访问权限,可以用宏或位掩码进行解读。

  • 文件类型:
S_ISREG(m)   // 普通文件
S_ISDIR(m)   // 目录
S_ISCHR(m)   // 字符设备
S_ISBLK(m)   // 块设备
S_ISFIFO(m)  // 管道
S_ISLNK(m)   // 符号链接
S_ISSOCK(m)  // 套接字
  • 文件权限:
    • 使用位掩码提取权限位,例如:
      • st_mode & S_IRUSR:所有者是否有读取权限。
      • st_mode & S_IWGRP:组是否有写入权限。

文件大小

  • st_size
    • 文件的总大小(以字节为单位)。
    • 如果是普通文件,它表示文件的长度。
    • 如果是目录,通常为 0。

示例

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

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <file>\n", argv[0]);
        return 1;
    }

    struct stat file_stat;
    if (stat(argv[1], &file_stat) == -1) {
        perror("stat");
        return 1;
    }

    printf("File: %s\n", argv[1]);
    printf("Size: %ld bytes\n", file_stat.st_size);
    printf("Type: ");
    if (S_ISREG(file_stat.st_mode)) printf("Regular File\n");
    else if (S_ISDIR(file_stat.st_mode)) printf("Directory\n");
    else if (S_ISCHR(file_stat.st_mode)) printf("Character Device\n");
    else if (S_ISBLK(file_stat.st_mode)) printf("Block Device\n");
    else if (S_ISFIFO(file_stat.st_mode)) printf("FIFO (Pipe)\n");
    else if (S_ISLNK(file_stat.st_mode)) printf("Symbolic Link\n");
    else if (S_ISSOCK(file_stat.st_mode)) printf("Socket\n");

    printf("Permissions: %o\n", file_stat.st_mode & 0777);
    printf("Last modified: %s", ctime(&file_stat.st_mtime));

    return 0;
}

access函数

功能:access 是一个用于检查文件访问权限的函数。它通过文件路径检测当前进程是否对该文件具有某种特定的访问权限,例如可读、可写、可执行或文件是否存在。

#include <unistd.h>

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

示例:检查文件是否存在

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

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

    if (access(filename, F_OK) == 0) {
        printf("File '%s' exists.\n", filename);
    } else {
        perror("File does not exist");
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值