如何检查字符串是否具有非托管C ++代码中的有效文件路径或目录路径格式?

问题描述 投票:5回答:4

我想知道如何检查(在非托管的Visual C ++代码中)字符串是否具有表示文件路径或文件夹路径的有效格式。在这种情况下,物理文件或文件夹路径本身可能存在也可能不存在。在我的情况下,检查正确的字符串格式是主要目标。我需要知道一个字符串是否具有正确的格式以成为有效的文件路径,还是没有?有很多关于C#的帖子,但是没有关于非托管C ++的帖子。如何在Visual C ++中的非托管C ++中执行此操作?

c++ filepath string-formatting
4个回答
6
投票

唯一的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.txtc:\direoctry。但是,如果foo已经存在,该怎么办?您将删除文件并在其位置创建目录吗?还是您会说它“很好”,然后在尝试创建目录时失败?我不知道答案,这种复杂性就是为什么我说“确保尝试的唯一方法”的原因-其他一切都只是在追尾或逼近正确性。

当然,如果我们考虑文件许可权,情况将变得更加复杂。

[反之亦然-这种问题通常称为“ TOCTOU”-“检查时间到使用时间”]

2
投票
如果结合了最新版本的boost,则可以使用FileSystem来为您完成工作,并解决所有常见问题(\ vs \\等...)。它还提供了一些其他功能(文件大小,权限等...)

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

希望有所帮助,


1
投票
我认为Mats Petersson的答案描述了真实的答案。我想指出一个常见的错误。假设以下功能:

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!
}
可能在检查后但在使用前变得无效。确保它确实存在的唯一方法是将其打开并保留文件句柄。

0
投票
这对我有用:

myFile

无需创建任何文件。无需Boost。 (我的第一条建议答案!)(我认为)
© www.soinside.com 2019 - 2024. All rights reserved.