我想知道如何检查(在非托管的Visual C ++代码中)字符串是否具有表示文件路径或文件夹路径的有效格式。在这种情况下,物理文件或文件夹路径本身可能存在也可能不存在。在我的情况下,检查正确的字符串格式是主要目标。我需要知道一个字符串是否具有正确的格式以成为有效的文件路径,还是没有?有很多关于C#的帖子,但是没有关于非托管C ++的帖子。如何在Visual C ++中的非托管C ++中执行此操作?
唯一的100%确定方法是“尝试”。您可以编写代码来确定简单的情况,但是总是会遇到麻烦,除非您还必须找出驱动器所在的文件系统,因为Windows允许使用“ junctions”,因此意味着解析整个路径一直到最后一部分。
这很简单:
std::ifstream test(proposedName);
if (!test)
{
std::cout << "The file doesn't exist" << std::endl;
}
如果您真的想花哨的话,可以看看errno
来确定它是“无效的文件名”还是“文件不存在”。但是总的来说,尝试第二个猜测文件名和路径的有效性是没有意义的,因为有太多的规则可能适用于您的特殊情况,也可能不适用于您的特定情况。
如果目录“ halfway”不存在,它将变得更加复杂。您只需解析路径,然后尝试创建目录(如果整个过程失败,则再次删除它)。但是,由于必须处理非规范路径,这一点使情况更加复杂。 c:\blah\..\.\foo\..\bar\xxx.9\..\..\bleurgh\papa.txt
是有效的文件名吗?为了解决这个问题,您必须首先对名称进行规范化。
PathCanonicalize
或它的朋友会为此提供帮助。但是它仍然充满了很难解决的复杂问题。
当然,您可以尝试编写正则表达式或类似的东西来捕获简单的案例,但最终仍会遇到难以理解的案例。
请注意,在某些情况下,路径可能看起来有效,但并非如此。假设我们有以下路径:PathCanonicalize
。现在,这看起来非常有效,我们可能必须在其中创建c:\directory\foo\bar.txt
和c:\direoctry
。但是,如果foo
已经存在,该怎么办?您将删除文件并在其位置创建目录吗?还是您会说它“很好”,然后在尝试创建目录时失败?我不知道答案,这种复杂性就是为什么我说“确保尝试的唯一方法”的原因-其他一切都只是在追尾或逼近正确性。
当然,如果我们考虑文件许可权,情况将变得更加复杂。
[反之亦然-这种问题通常称为“ TOCTOU”-“检查时间到使用时间”]c:\directory\foo
这里是链接。
#include <boost/filesystem.hpp> string filePath= "C:\Temp\myExample.txt"; if (boost::filesystem::exists(filePath)) // does filePath actually exist? cout<<"This is a valid file"; else cout<<"The file does not exist";
应该在某个时候在官方的C ++中,这里有完整的详细信息。
http://www.boost.org/doc/libs/1_47_0/libs/filesystem/v3/doc/tutorial.html
希望有所帮助,
http://en.cppreference.com/w/cpp/experimental/fs
然后以这种方式使用它:
bool fileExists(const char* fileName) { std::ifstream test(fileName); return (test) ? true : false; }
这里有一个巨大的比赛条件。 if (fileExists(myFile))
{
// assume myFile is a valid file
// WRONG!
}
可能在检查后但在使用前变得无效。确保它确实存在的唯一方法是将其打开并保留文件句柄。
myFile
无需创建任何文件。无需Boost。 (我的第一条建议答案!)(我认为)