以前有人问过这个问题,但几乎所有的答案都归结为realpath
函数。这对不存在的路径无效。我需要一个解决方案,我想调用POSIX或OSX框架函数,而不是手动解析字符串。
重申一下:我需要一个函数,它接受一个任意的路径字符串,并返回不带"./"或".."元素的等效路径。
有这样的解决方案吗?
你确定有这样的解决方案吗?我认为不是(因为有些目录可能是打字错误或要创建的符号链接)。
您希望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上只使用系统调用(2)。然后你必须考虑所有奇怪的情况。。。此外,在realpath(1)上使用strace(1)来了解它在做什么。。。
或者,不必关心目录中包含../
或符号链接的非规范路径,只需将当前目录(请参阅getcwd(3))预先设置为任何不以/
开头的路径。。。。。。。