【问题标题】:Open file relative to executed module打开相对于执行模块的文件
【发布时间】:2011-06-19 07:13:35
【问题描述】:

我知道,打开一个文件,将其限制在与执行模块相同的目录中,这不是最好的主意。但是,有一个工具,我被命令编程,具有精确的这些规范。

文件路径有一个参数,可以是文件的绝对路径,也可以是文件名,假设它位于当前目录中。

我不想使用 WinAPI 函数 GetCurrentDirectory 来保持可移植性。如果文件无法打开,该工具应该会失败。

通常我使用 boost::filesystem 作为 I/O 库。因此,我对标准库不是很熟悉。

我的第一个想法是将文件路径传递给 std::ifstream::open()。但这似乎不适用于相对路径。

我可以做些什么来满足我的要求?

【问题讨论】:

  • 您开始谈论打开与可执行文件位于同一目录中的文件。然后你说说当前目录。这些不一定相同。事实上,我什至会说命令行程序的当前目录与程序自己的目录相同是罕见。请说明你真正需要的。

标签: c++ io relative-path ifstream


【解决方案1】:

不幸的是,没有简便的方法可以做到这一点。特别是,GetCurrentDirectory 可能不会返回与您的可执行模块相同的目录 - 在 Windows 上,只需打开一个通用对话框文件选择框就会导致您当前的目录发生变化!在其他平台上,您根本不可能从同一个目录开始(再说一次,您可能在那里也没有写入权限,但这也适用于现代 Windows...)

在 Windows 上,一般来说,您需要使用 GetModuleFileName 来查找模块的位置,然后去掉文件名部分。在 Linux 上,在 /proc/self/exe 上调用 readlink 以获得主可执行文件,或者在 /proc/self/maps 中寻找与动态库的代码段对应的映射。在其他操作系统上,我不知道。

【讨论】:

  • 你是对的。我已经知道了,但就像我说的。我希望我不需要使用 WinAPI。
  • @FrEEzE2046:编写您自己的函数来获取文件名,您在 Windows 和 Linux(甚至其他地方)上实现的方式不同。然后,您通过瘦包装器保持可移植性。但是,尤其是在非 Windows 系统上,您应该考虑更好的想法;您似乎知道使用可执行文件的位置是您在问题中指出的一个相当糟糕的解决方案。
  • @Fred Nurk - 将文件限制在与可执行文件相同的文件夹中是我的规范的一部分。因此,我提到了这一点,但是 ... ;)
  • @FrEEzE2046:我知道你做到了;我鼓励你改变它。 :)
【解决方案2】:

只需传递相对文件名。它将相对于当前目录。

【讨论】:

  • 当前目录在 Windows 上变化太大。例如,打开文件对话框会更改您的当前目录,甚至跨线程。出于这个原因,您应该永远不要在 win32 上使用当前目录。
  • 这就是问题所在。 std::ifstream 是否处理相对文件路径?
  • 相对路径的存在本身并不是 C++ 标准的一部分 :) 通常,假设您将从同一个目录开始是不可移植作为您的可执行文件。而且它只是不正确将保留在那里。
  • (也就是说,在 Windows 上,所有标准 C 或 C++ I/O 函数都将处理相对路径 - 但请不要将它们用于此目的)
  • 正在考虑...我将使用传递给我的 DllMain 的模块句柄 ;)
猜你喜欢
  • 2021-09-03
  • 2012-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-29
  • 1970-01-01
  • 2010-09-19
  • 1970-01-01
相关资源
最近更新 更多