我正在std::filesystem
为游戏创建 Lua 绑定,并且我想确保稍后使用该绑定的 mod 不依赖于 Windows 的不区分大小写。
例如,在 Windows 上fopen("foo.txt", "w")
后跟fopen("Foo.txt", "r")
会读取文件,而在 Linux 上则不会,因为 Linux 区分大小写。这不仅涉及文件名,还涉及整个路径,因为假设bar/
存在,fopen("bar/baz.txt", "w")
后跟fopen("Bar/baz.txt", "r")
在 Windows 上可以工作,但在 Linux 上也失败。因此,虽然该 mod 可以在 Windows 上运行,但对于 Linux 用户来说它会崩溃,这是我想防止的。
以前,我通过使用此处的代码“使”Linux 不区分大小写来解决这个问题,该代码本质上是通过迭代目录中的所有条目并检查名称是否不区分大小写匹配来构建一条路径,一次一个父目录。
然而,这个解决方案的代码不是很优雅,而且相当大,现在我决定通过“使”Windows 区分大小写来做完全相反的事情,我希望也许有一些功能可以在 Windows 上使用获取文件的真正区分大小写的路径,这样在两个fopen("Foo.txt", "r")
操作系统上都会失败。
我在谷歌上搜索了很多,并在SO上查找了以前问过这个问题的任何其他人,但大多数答案要么是尖刻的“为什么有人需要这个”,要么是执行与我上面链接的当前解决方案相同的操作。
我尝试过使用GetFullPathName()
例如将其放入foo.cpp
文件中,但它打印C:\Users\<user>\Desktop\Foo.cpp
,所以没有用,因为我需要Foo.cpp
与实际文件名相同的大小写:
#include <iostream>
#include <windows.h>
int main() {
char filename[] = "Foo.cpp";
char fullFilename[MAX_PATH];
GetFullPathName(filename, MAX_PATH, fullFilename, nullptr);
std::cout << fullFilename << std::endl;
}
谢谢
策略是打开文件并检索实际打开的文件路径(With
GetFinalPathNameByHandle
):重要的是不要打开文件,
FILE_FLAG_POSIX_SEMANTICS
因为这样就不会发生不区分大小写的路径转换。为此,您不需要文件的读/写权限。如果路径不存在,这将失败,在这种情况下,您可能需要遍历子目录以查看它们的大小写是否正确。我认为
std::filesystem::canonical
Microsoft STL 也是如此。或者,您可以在 Windows 上实现 Lua
fopen
以使用FILE_FLAG_POSIX_SEMANTICS
. 这将不允许您读取写入Foo.txt
时间foo.txt
,并且允许您拥有两个不同的文件Foo.txt
和foo.txt
,即使在 Windows 上也是如此。