You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据文件名获取目标文件所在目录的文件描述符

解答

完全可以通过标准POSIX接口拿到目标文件所在目录的文件描述符,不需要特殊内核接口,具体实现逻辑和注意点如下:

核心实现步骤

针对你举的/home/user/files/test.txt例子,要拿到files目录的fd,流程很直接:

  • 先把完整路径拆成两部分:父目录路径/home/user/files、目标文件名test.txt
  • 调用open()打开父目录路径,打开标志必须带O_RDONLY | O_DIRECTORY,其中O_DIRECTORY用来保证打开的目标一定是目录,避免路径被篡改指向普通文件带来安全问题,返回的文件描述符就是utimensat()需要的dirfd参数
  • 调用utimensat()时,dirfd传刚才拿到的目录fd,pathname传拆分出的目标文件名即可
  • 操作完成后调用close()释放目录fd,避免文件描述符泄漏

路径拆分不要自己写字符串切割逻辑,容易被多斜杠、末尾斜杠、相对路径等边界情况搞出bug,直接用POSIX标准的dirname()和basename()函数即可,注意这两个函数会修改传入的字符串缓冲区,使用前一定要提前拷贝原路径字符串。

更简洁的替代方案

如果你只是单次修改文件时间戳,完全不需要手动拆分路径、打开目录:直接给utimensat()的dirfd参数传特殊值AT_FDCWD,pathname参数传完整的文件路径(不管是绝对路径还是相对路径都可以)即可,纳秒级时间戳的精度不会受任何影响,这个写法是POSIX标准规定的,全平台兼容,代码量少还不容易出错。
只有当你需要反复操作同一个目录下的大量文件时,才需要提前打开目录拿fd复用,减少重复路径解析的开销。

参考示例代码

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <libgen.h>
#include <string.h>
#include <limits.h>

// 手动获取目录fd的实现
int set_file_ts_ns(const char *full_path, struct timespec ts[2]) {
    char dir_buf[PATH_MAX] = {0};
    char base_buf[PATH_MAX] = {0};
    strncpy(dir_buf, full_path, PATH_MAX - 1);
    strncpy(base_buf, full_path, PATH_MAX - 1);

    char *dir_path = dirname(dir_buf);
    char *file_name = basename(base_buf);

    int dirfd = open(dir_path, O_RDONLY | O_DIRECTORY);
    if (dirfd < 0) {
        perror("open parent dir failed");
        return -1;
    }

    int ret = utimensat(dirfd, file_name, ts, 0);
    if (ret < 0) {
        perror("utimensat call failed");
        close(dirfd);
        return -1;
    }

    close(dirfd);
    return 0;
}

// 简洁写法,无需手动处理目录fd
int set_file_ts_ns_simple(const char *full_path, struct timespec ts[2]) {
    int ret = utimensat(AT_FDCWD, full_path, ts, 0);
    if (ret < 0) {
        perror("utimensat call failed");
        return -1;
    }
    return 0;
}

注意事项

  • 打开父目录时需要当前进程对该目录有读权限,否则open()会返回权限错误
  • 如果需要修改符号链接本身的时间戳而非其指向的文件,记得给utimensat()的flags参数加AT_SYMLINK_NOFOLLOW
  • 如果传入的文件路径是相对路径,AT_FDCWD的写法会自动以进程当前工作目录为基准解析路径,不需要额外处理

内容的提问来源于stack exchange,提问作者programme3219873

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:24:20