如何在 Windows 上从 C++11 统计信息对象的文件序列号中查找文件名

How to find the filename from a C++11 stat object's file serial number on Windows

本文关键字:文件 序列号 文件名 查找 对象 信息 Windows 上从 统计 C++11      更新时间:2023-10-16

因为在Windows中,使用Visual Studio,__FILE__宏可以提供小写字符串,并且因为我需要知道正确大小写的文件名(用户认为),我正在尝试研究如何将Windows上的全小写路径转换为正确大小写的路径。

看起来使用统计信息获取有关文件的信息可能是一个很好的起点。

但是,给定一个统计对象,我如何才能获得文件名?

#include <sys/stat.h>
#include <string>
void test()
{
std::string file_name = "C:\WiNdoWs";
struct stat statbuf;
int stat_ok = stat(file_name.c_str(), &statbuf);
auto file_serial_number = statbuf.st_ino;
std::string full_file_name = ???;
}

或者还有其他 C++11 方法可以实现这一点吗?它只需要在Windows上运行,因此特定于Windows的解决方案(带有代码)就可以了。

我们希望这样做,而不添加对boost文件系统或Qt的依赖,或者移动到C++17。

更新 1

对于上下文,代码位于仅标头测试框架中,该框架旨在根据包含测试的源文件的名称创建一些输出文件 - 因此名为DemoTest.cpp的测试文件将生成名称以DemoTest...开头的输出文件。

我们试图解决的问题是,对于某些Visual Studio编译器设置,输出文件名以demotest...开头

。因此,这意味着stat调用在编译时生成__FILE__的同一源文件上运行。

更新 2

事实证明,在Visual Studio 2017中调试时,statbuf.st_ino值为零 - 大概是因为该值表示Unix索引节点,而Windows上没有这样的东西。

所以这整个方法行不通。

还有其他选择吗?

恐怕你会再次陷入困境,因为这取决于用户如何调用编译器。如果你说(例如在一个制作文件中)

A.o: A.c
$(CC) A.c -o a.o

Windows 不会抱怨输出文件的大小写,因为这两种情况都引用相同的对象输出。 但A.c的情况不同。 如果您尝试cc A.c并且源文件作为a.c存储在文件系统中,则只有一种方法可以知道文件存储在文件系统中的实际名称...即,在目录中搜索文件,并在找到与要搜索的文件匹配的文件时停止。 因此,这是一种复杂(且昂贵)的方式,因此编译器通常不会遵循它,因此它将根据您传递给它的名称进行操作。 对于#include文件也是如此,这些文件在您的源代码中有些命名......我修改了字符名称的大小写,编译器不会抱怨,除非修改给你一个不存在的文件,在这种情况下,你会得到一个file not found的投诉。

结论是:使用正确的名称,编译器将有确切的方式来拼写文件名。如果你不这样做,编译器不会在这方面提供帮助......_If你告诉我编译a.c我会告诉你__FILE__匹配a.c,即使实际文件名是A.C

编译器可能会给你不同的文件大小写,因为你给编译器提供了不同的大小写(通过拼写错误的命令行或拼写错误的#include指令)小心使用案例,并且您将收到名称中的正确大小写。