【问题标题】:A system function to convert relative path to full path that works even for non-exsting paths?将相对路径转换为完整路径的系统函数,即使对于非现有路径也有效?
【发布时间】:2016-04-15 16:50:29
【问题描述】:

之前有人问过这个问题,但几乎所有答案都归结为realpath 函数。这不适用于不存在的路径。我需要一个解决方案,我想调用 POSIX 或 OS X 框架函数,而不是手动解析字符串。

重申一下:我需要一个函数,它采用任意路径字符串并返回没有“./”或“..”元素的等效路径。

有这样的解决方案吗?

【问题讨论】:

  • 您应该更详细地说明您真正想做的事情,并给出几个示例(包括路径中引用的目录不存在的一些示例)
  • @BasileStarynkevitch:在我看来,我已经非常清楚地解释了我想要做什么。需要澄清什么?
  • 你如何处理/tmp/someinexistentdirectory/foobar/tmp/someinexistentdirectory/../foobar?我对你的问题投了反对票,因为你没有告诉怎么做。
  • @BasileStarynkevitch:我看不出该路径有什么需要做的,就这样就可以了。
  • 公平地期望这个功能会出现在标准库中,这个问题不会赢得反对票。路径是一种符号方案,与 inode 或实现可以施加的任何约束无关当将路径输入它时。老实说,这是一个特殊的 POSIX 限制,而不是在案子周围扬起灰尘,让人们和你自己感到困惑。

标签: c++ objective-c macos path relative-path


【解决方案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 由其他一些正在运行的进程...

也许你想使用像QtPOCO 这样的框架;他们可能会为你提供足够好的东西......

实际上,我建议您完全自己编写 betterrealpath 函数,在 Linux 上使用 syscalls(2)。然后,您将不得不考虑所有奇怪的情况...另外,在realpath(1) 上使用strace(1) 以了解它在做什么...

或者,不要关心包含../ 的非规范路径或目录中的符号链接,只需将当前目录(参见getcwd(3))添加到任何不以/ 开头的路径...... ..

【讨论】:

  • 一定有解决办法。例如,在 Windows 上有一个。如果系统不知道更好(例如路径不存在),它至少应该扩展“。”和“..”正确。
  • 这是一个非常错误的推理。 Windows 文件系统具有根本不是 POSIX 的语义。 POSIX 有硬链接,甚至可能在目录上......
  • Windows 也有链接。此外,我不希望系统猜到任何东西。我只需要它来清理现有路径,并将不存在的路径转换为绝对形式。
  • 没有是一个解决方案。也许你的问题足够有限,它有一个解决方案,但一般来说它不是真的。
  • 你不想自己写函数,你不想使用外部库函数,而且 Posix 没有提供合适的函数——你将不得不放宽一个要求。
猜你喜欢
  • 2012-04-01
  • 2014-10-29
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
  • 2011-11-07
  • 2011-05-02
相关资源
最近更新 更多