Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Linux上获得规范化(规范化)文件路径;即使文件系统上不存在文件路径";?(在C程序中)_C_Linux_File_Unix_Filepath - Fatal编程技术网

如何在Linux上获得规范化(规范化)文件路径;即使文件系统上不存在文件路径";?(在C程序中)

如何在Linux上获得规范化(规范化)文件路径;即使文件系统上不存在文件路径";?(在C程序中),c,linux,file,unix,filepath,C,Linux,File,Unix,Filepath,我在这个话题上做了很多研究,但没有得到任何实质性的东西。 通过规范化/规范化,我的意思是从文件路径中删除所有“.”、“.”、多个斜杠等,并获得一个简单的绝对路径。 e、 g “/rootdir/dir1/dir2/dir3/../../../dir4////”to “/rootdir/dir1/dir2/dir4” 在windows上,我有GetFullPathName(),我可以得到规范的文件路径名,但在Linux上,我找不到任何这样的API可以为我做同样的工作, realpath()存在,但

我在这个话题上做了很多研究,但没有得到任何实质性的东西。 通过规范化/规范化,我的意思是从文件路径中删除所有“.”、“.”、多个斜杠等,并获得一个简单的绝对路径。 e、 g

“/rootdir/dir1/dir2/dir3/../../../dir4////”to “/rootdir/dir1/dir2/dir4”

在windows上,我有GetFullPathName(),我可以得到规范的文件路径名,但在Linux上,我找不到任何这样的API可以为我做同样的工作, realpath()存在,但即使realpath()也需要文件系统上存在文件路径才能输出规范化路径,例如,如果路径/rootdir/dir1/dir2/dir4不在文件系统上,则realpath()将对上述指定的复杂文件路径输入抛出错误。 是否有任何方法可以获得规范化的文件路径,即使文件系统中不存在该路径

realpath(3)无法解析丢失的文件名。
但是GNU核心实用程序()有一个程序realpath(1),它类似于realpath(3)函数,但有选项:
-m、 --规范化缺少的路径组件不需要存在

您的任务可以通过coreutils源文件lib/canonicalize.c中的canonicalize\u filename\u mode()函数来完成。

canonicalize\u filename\u mode()
from
Gnulib
是一个很好的选择,但不能用于商业软件(GPL许可证)

我们使用以下依赖于
cwalk
库的实现:

#define _GNU_SOURCE

#include <unistd.h>
#include <stdlib.h>

#include "cwalk.h"

/* extended version of canonicalize_file_name(3) that can handle non existing paths*/
static char *canonicalize_file_name_missing(const char *path) {
    char *resolved_path = canonicalize_file_name(path);
    if (resolved_path != NULL) {
        return resolved_path;
    }
    /* handle missing files*/
    char *cwd = get_current_dir_name();
    if (cwd == NULL) {
        /* cannot detect current working directory */
        return NULL;
    }
    size_t resolved_path_len = cwk_path_get_absolute(cwd, path, NULL, 0);
    if (resolved_path_len == 0) {
        return NULL;
    }
    resolved_path = malloc(resolved_path_len + 1);
    cwk_path_get_absolute(cwd, path, resolved_path, resolved_path_len + 1);
    free(cwd);
    return resolved_path;
}
定义GNU源
#包括
#包括
#包括“cwalk.h”
/*规范化文件名(3)的扩展版本,可处理不存在的路径*/
静态字符*规范化文件\文件名\缺失(常量字符*路径){
char*resolved_path=规范化_文件名(路径);
if(已解析路径!=NULL){
返回解析的路径;
}
/*处理丢失的文件*/
char*cwd=get_current_dir_name();
如果(cwd==NULL){
/*无法检测当前工作目录*/
返回NULL;
}
size\u t resolved\u path\u len=cwk\u path\u get\u absolute(cwd,path,NULL,0);
if(已解析路径长度==0){
返回NULL;
}
解析路径=malloc(解析路径长度+1);
cwk_path_get_absolute(cwd,path,resolved_path,resolved_path_len+1);
免费(cwd);
返回解析的路径;
}

只是一个旁注:如果
dir3
是指向另一个目录的符号链接,那么您的规范化并不像示例中预期的那样有效。谢谢@dhke,我理解这一点-但对于我的用例,我将在文件系统上有目录,所以我不担心这一点。GetFullPathname和realpath可能重复,但请注意,GetFullPathname和realpath都不是真正的规范,因为它们不尊重符号链接和类似的内容。在这种情况下:从末尾开始删除节点,直到找到现有路径为止。(这基本上就是
mkdir-p/some/path
所做的…)顺便问一下:如果两个目录项链接到同一个inode,会发生什么情况?您可以添加一点类似于如何在代码中使用它的内容吗。我一直在尝试在linux机器上构建,但如果不是绝对的,就不能包含canonicalize.h