相对于执行模块打开文件

3

我知道,将文件限制为必须放置在执行模块相同的目录下并不是最好的想法。但是,我被要求编写一个具有这些确切规格的工具。

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

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

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

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

我该怎么做才能满足我的需求?


4
你开始谈论打开与可执行文件位于同一目录中的文件,然后你又谈到了当前目录,但这两者并不一定相同。事实上,我甚至认为命令行程序的当前目录很少与程序自身所在的目录相同。请澄清你真正需要哪个。 - Rob Kennedy
2个回答

3

很遗憾,没有易于移植的方法来实现这一点。特别地,在Windows平台上,打开常用对话框文件选择框将导致当前目录更改,因此GetCurrentDirectory可能不会返回与可执行模块相同的目录!在其他平台上,您可能根本不会从相同的目录开始(但是您可能也无权在那里写入,但这也适用于现代Windows...)

在Windows平台上,通常情况下,您需要使用GetModuleFileName查找模块的位置,然后删除文件名部分。在Linux上,对主可执行文件调用/proc/self/exe上的readlink,或者在/proc/self/maps中寻找对应于动态库代码段的映射。在其他操作系统上,我不知道。


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

-3

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


1
当前目录在Windows上经常变化。例如,打开文件对话框会在不同的线程中更改当前目录。因此,您绝不能在Win32上使用当前目录。 - bdonlan
那就是问题所在。std::ifstream能处理相对文件路径吗? - 0xbadf00d
话虽如此,在Windows上,所有标准的C或C++ I/O函数都可以处理相对路径 - 但是,请不要使用它们来处理这个问题。 - bdonlan
1
考虑到这一点...我将使用传递给我的DllMain的模块句柄;) - 0xbadf00d
需求是“当前目录”。传递相对文件名即可实现。因此,我不明白为什么要使用-1... - Frederik Slijkerman
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接