之前已经问过这个问题,但几乎所有答案都归结为realpath
函数。哪个不适用于不存在的路径。我需要一个解决方案,我想调用POSIX或OS X框架函数而不是手工解析字符串。
重申:我需要一个带有任意路径字符串的函数,并返回没有“./”或“..”元素的等效路径。
有这样的解决方案吗?
答案 0 :(得分:1)
你确定可以有这样的解决方案吗?我相信不是(因为某些目录可能是拼写错误或要创建的符号链接)。
您希望betterrealpath
函数在/tmp/someinexistentdirectory/foobar
返回什么内容?也许用户意图是从$HOME
到/tmp/someinexistentdirectory
的符号链接?或许这是一个错字,用户想要/tmp/someexistentdirectory/foobar
......?那么/tmp/someinexistentdirectory/../foobar
呢?它应该被规范化为/tmp/foobar
吗?为什么呢?
也许使用第一个dirname(3),然后对其进行realpath(3),然后附加参数的basename(3)就足够了?在C中类似于:
const char*origpath = something();
char*duppath = strdup(origpath);
if (!duppath) { perror("strdup"); exit(EXIT_FAILURE); };
char*basepath = basename(duppath);
char*dirpath = dirname(duppath);
char*realdirpath = realpath(dirpath, NULL);
if (!realdirpath) { perror("realpath"); exit(EXIT_FAILURE); };
char* canonpath = NULL;
if (asprintf(&canonpath, "%s/%s", realdirpath, basepath) <= 0)
{ perror("asprintf"); exit(EXIT_FAILURE); };
free (duppath), duppath = NULL;
basepath = NULL, dirpath = NULL;
/// use canonpath below, don't forget to free it
当然,该示例不适用于/tmp/someinexistentdirectory/foobar
但适用于/home/violet/missingfile
,假设您的主目录为/home/violet/
且可访问(可读且可执行) )......
随意改进或适应C ++上面的代码。不要忘记处理失败。
请记住,i-nodes是POSIX文件系统的核心。一个文件(包括一个目录)可以有一个,零个或几个文件路径......目录(或文件)名称可以是rename
- d由其他一些正在运行的进程...
也许你想使用像Qt或POCO这样的框架;他们可能会为你提供足够好的东西......
实际上,我建议您完全自己编写betterrealpath
函数,在Linux上仅使用 syscalls(2)。然后,您必须考虑所有奇怪的案例......另外,在strace(1)上使用realpath(1)来了解它在做什么......
或者,不要关心目录中包含../
或符号链接的非规范路径,只需将当前目录(请参阅getcwd(3))添加到不以{{{}开头的任何路径1}} .......