Is the behaviour of ifstream::ifstream on directories well-defined?
根据C++ 11标准,是行为的
指定,还是依赖于系统?
在上下文方面,我试图避免使用boost::filesystem和类似的库,因为它们会导致不相关的可移植性问题。
编辑:根据我能找到的,我应该得到一个有效的ifstream(如果并且只有当目录存在时才是'good()'。这可能提供了一种比使用boost::filesystem更可移植的方法来测试目录是否存在,因为后者要求您链接更多的库。
- 目录不是文件。
- 你希望它能做什么?
- 目录是UNIX上的文件。请参阅unix.stackexchange.com/questions/197439/…
- 如果目录存在,我希望它返回一个很好的ifstream()。编辑Q.
- 用代替?
- NathanOliver有一个我指定C++ 11的原因…
- 对不起,我没看到标题上的标签。我已经编辑它从标题中删除标签,而用C++ 11标记Q。
- "目录是Unix上的一个文件。"—但不在其他OSS上—所以这最好取决于系统。
- 说目录是UNIX中的文件有点误导,因为它们不支持所有相同的操作,在任何情况下都不相关,因为您的问题是关于便携式C++而不是UNIX。
- @Interjay让我更具体一点。C++ 11标准是指FPEN。pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.htm‌&误8203;l提供了一些类似于fopen规范的内容,但我认为它是特定于posix的。你知道我在哪里能找到fopen的规格吗?
- 即使在UNIX中,也只应该使用特定选项打开目录,这些选项不容易映射到文件*或std::stream。所以简单的答案是不。
- @gemtylor note pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.htm‌&8203;l显然允许在目录上使用fopen。例如,请参阅错误eisdir,它防止打开具有写访问权限的dir。
- fopen的可移植引用是C标准,它没有说它可以打开目录。您链接到的是POSIX版本,它有一些扩展。
- C++标准根本不提及目录或UNIX。如果您希望您的程序在unixes上工作,您需要一些东西来保证您在unixes上的行为。C++标准不是这样的文档。实际上,如果指定std::ios_base::in作为打开模式,则可能会获得good()流。但你不太可能从中得到任何好的东西。
- 另外,开头的一行清楚地表示文件,除了父目录和方向之外,没有dir的实例。再试一次。
- @gemtylor尝试搜索"命名文件是一个目录,模式需要写访问权限。"
标准似乎没有在其散文中的任何地方提到"目录"的概念。这里提到了eisdir errno和镜像posix的一般意图,但仅"可用于报告低级条件"。我会说系统依赖,不可移植。
- 委员会希望在某个时候纠正这一点。有一个技术规范来解决这个问题。编程语言-C++文件系统技术规范OpenStdOrg/JTC1/SC22/WG21/DOCS/PoSs/2014/N4100.PDF,但它看起来没有进入C++ 17。
- @理查德钱伯斯很有趣。它明确地指出dir是一个文件。
- @mohan最好把它看作是filesystem技术规范,它说filesystem函数将目录作为文件来表示。谁知道底层操作系统操作系统在做什么,标准库在引擎盖下跳过了什么环,以便为该规范提供一个接口。
According to what I can find, I should get a valid ifstream (one that is good() if and only if the directory exists.
标准并不能保证这个结果。我不会将它用作检查目录是否存在的机制。
当您仅限于使用C++ 11时,您最好的选择是使用由适当的预处理器宏包围的依赖于平台的API调用。
1 2 3 4 5 6 7
| #if defined(_WINDOWS)
// Use Windows specific APIs
#elif defined(_Linux)
// Use Linux specific APIs
#elif defined(_MacOS) ???
// Use MacOS specific APIs
#endif |
更多信息:
对于Windows:如何检查C中的Windows上是否存在目录?对于Linux:检查UNIX中是否存在目录(系统调用)