【问题标题】:Getting absolute path of a file获取文件的绝对路径
【发布时间】:2010-09-18 17:52:49
【问题描述】:

如何在 Unix 上将相对路径转换为 ​​C 中的绝对路径? 有没有方便的系统函数呢?

在 Windows 上有一个 GetFullPathName 函数可以完成这项工作,但我在 Unix 上没有找到类似的东西......

【问题讨论】:

    标签: c unix path filesystems absolute


    【解决方案1】:

    还有一个小型路径库cwalk 可以跨平台工作。它有 cwk_path_get_absolute 这样做:

    #include <cwalk.h>
    #include <stdio.h>
    #include <stddef.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
      char buffer[FILENAME_MAX];
    
      cwk_path_get_absolute("/hello/there", "./world", buffer, sizeof(buffer));
      printf("The absolute path is: %s", buffer);
    
      return EXIT_SUCCESS;
    }
    

    输出:

    The absolute path is: /hello/there/world
    

    【讨论】:

      【解决方案2】:

      stdlib.h 中尝试realpath()

      char filename[] = "../../../../data/000000.jpg";
      char* path = realpath(filename, NULL);
      if(path == NULL){
          printf("cannot find file with name[%s]\n", filename);
      } else{
          printf("path[%s]\n", path);
          free(path);
      }
      

      【讨论】:

        【解决方案3】:

        也可以试试“getcwd”

        #include <unistd.h>
        
        char cwd[100000];
        getcwd(cwd, sizeof(cwd));
        std::cout << "Absolute path: "<< cwd << "/" << __FILE__ << std::endl;
        

        结果:

        Absolute path: /media/setivolkylany/WorkDisk/Programming/Sources/MichailFlenov/main.cpp
        

        测试环境:

        setivolkylany@localhost$/ lsb_release -a
        No LSB modules are available.
        Distributor ID: Debian
        Description:    Debian GNU/Linux 8.6 (jessie)
        Release:    8.6
        Codename:   jessie
        setivolkylany@localhost$/ uname -a
        Linux localhost 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
        setivolkylany@localhost$/ g++ --version
        g++ (Debian 4.9.2-10) 4.9.2
        Copyright (C) 2014 Free Software Foundation, Inc.
        This is free software; see the source for copying conditions.  There is NO
        warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
        

        【讨论】:

        • 100K 的路径?!确定5K就够了吗?还是 PATH_MAX?
        • .... 因为getcwd 解析了当前工作目录,对于“/some/file/compiled/with/absolute.name`的__FILE__,代码可能会失败”
        【解决方案4】:

        使用realpath()

        realpath() 函数应派生, 从指向的路径名 file_name,绝对路径名 命名相同的文件,其分辨率 不涉及“.”、“..”或 符号链接。生成的路径名 应存储为空终止 字符串,最大为{PATH_MAX} 字节,在指向的缓冲区中 resolved_name.

        如果resolved_name 是一个空指针, realpath() 的行为是 实现定义。


        以下示例生成一个 文件的绝对路径名 由符号链接路径标识 争论。生成的路径名是 存储在实际路径数组中。

        #include <stdlib.h>
        ...
        char *symlinkpath = "/tmp/symlink/file";
        char actualpath [PATH_MAX+1];
        char *ptr;
        
        
        ptr = realpath(symlinkpath, actualpath);
        

        【讨论】:

        • “加一”不是必须的,但不会造成任何伤害。
        • Windows 上的 GetFullPathName 也适用于不存在的文件。 realpath 要求路径存在。当您想创建路径或文件时,这种方式很糟糕。
        • 实际路径包含绝对路径,但ptr包含什么?
        • @JonathanLeffler:PATH_MAX 是“整个文件名长度的统一系统限制(如果有)”,因此不包括 realpath 添加的终止 nul。因此需要 +1。
        • @EML +1 不是必需的。来自 POSIX limits.h 基本原理:“IEEE PASC 解释 1003.1 #15 解决了标准与路径名定义和 {PATH_MAX} 描述的不一致问题,允许应用程序开发人员分配 {PATH_MAX} 或 {PATH_MAX}+1 个字节。通过更正 {PATH_MAX} 定义以包含空字符来消除不一致。通过此更改,之前分配 {PATH_MAX} 字节的应用程序将继续成功。"
        猜你喜欢
        • 2012-04-24
        • 2016-11-19
        • 1970-01-01
        • 1970-01-01
        • 2013-04-11
        • 1970-01-01
        • 2021-10-18
        相关资源
        最近更新 更多