0

According to the C++11 standard, is the behaviour of

ifstream in(".");

specified, or is it system-dependent?

For context, I'm trying to avoid using boost::filesystem and similar libraries because they cause unrelated portability problems.

Edit: According to what I can find, I should get a valid ifstream (one that is 'good()' if and only if the directory exists. This potentially gives a more portable way of testing whether a directory exists than using boost::filesystem because the latter requires you to link against more libraries.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
Mohan
  • 7,302
  • 5
  • 32
  • 55
  • A directory isn't a file. – πάντα ῥεῖ Oct 10 '18 at 16:08
  • 2
    What do you expect it to do? – n. m. could be an AI Oct 10 '18 at 16:09
  • 1
    A directory IS a file on Unix. See https://unix.stackexchange.com/questions/197439/how-is-a-directory-a-special-type-of-file – Mohan Oct 10 '18 at 16:10
  • What I expect it to do is to return an ifstream that is good() if the directory exists. Editing q. . – Mohan Oct 10 '18 at 16:11
  • Use [``](https://en.cppreference.com/w/cpp/filesystem) instead? – NathanOliver Oct 10 '18 at 16:11
  • 1
    @NathanOliver There's a reason I specified C++ 11… – Mohan Oct 10 '18 at 16:12
  • 1
    Sorry, I didn't see the tag in the title. I've edited it to remove the tag from the title and instead tag the Q with [tag:c++11] – NathanOliver Oct 10 '18 at 16:13
  • "A directory IS a file on Unix." - but not on other OSs - so this must be at best system-dependent. –  Oct 10 '18 at 16:16
  • 1
    Saying that a directory is a file in Unix is somewhat misleading as they don't support all the same operations, and in any case not relevant here because your question is about portable C++ and not Unix. – interjay Oct 10 '18 at 16:16
  • @interjay let me be more specific. The C++ 11 standard refers to fopen. http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html gives something that looks like a spec. for fopen, but I think it's POSIX-specific. Do you know where I can find a specification for fopen? – Mohan Oct 10 '18 at 16:18
  • 1
    Even in unix, you are only supposed to open directories using specific options, which don't map easily onto FILE* or std::stream. So easy answer is no. – Gem Taylor Oct 10 '18 at 16:18
  • @GemTaylor note http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html clearly allows use of fopen on directories. E.g. see error EISDIR which prevents opening of dirs with write access. – Mohan Oct 10 '18 at 16:20
  • The portable reference for `fopen` is the C standard, which doesn't say it can open directories. What you linked to is the POSIX version which has some extensions. – interjay Oct 10 '18 at 16:21
  • 2
    The C++ standard doesn't mention directories or Unix at all. If you want your program to work on Unixes, you need something that guarantees you behaviour on Unixes. The C++ standard isn't such a document. In practice you are likely to get a `good()` stream if you specify `std::ios_base::in` as the open mode. You are not likely to get any good `read`s from it though. – n. m. could be an AI Oct 10 '18 at 16:22
  • Also, The opening line clearly says file, and there are no instances of dir except for parent directory and direction. Try again. – Gem Taylor Oct 10 '18 at 16:22
  • @GemTaylor Try searching for "The named file is a directory and mode requires write access." – Mohan Oct 10 '18 at 16:24

2 Answers2

2

The standard does not seem to have a mention of the concept of a "directory" anywhere in its prose. There is a mention of the EISDIR errno and a general intention to mirror posix, but only "may use to report low-level conditions". I would say system-dependent and not portable.

  • 2
    The Committee is looking to correct this at some point. There is a technical specification to address it. Programming Languages — C++ — File System Technical Specification http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf but it looks like it did not make it into C++17. – Richard Chambers Oct 10 '18 at 16:55
  • @RichardChambers interesting. That states unambiguously that a dir is a file. – Mohan Oct 10 '18 at 17:26
  • @Mohan it might be better to think of it as the `filesystem` technical spec says that the `filesystem` function presents a directory as a file. Who knows what the underlying operating system OS is doing and what hoops the Standard Library jumps through under the hood in order to present an interface to that specification. – Richard Chambers Oct 10 '18 at 18:55
0

According to what I can find, I should get a valid ifstream (one that is good() if and only if the directory exists.

That result is not guaranteed by the standard. I wouldn't use it as a mechanism to check whether a directory exists.

When you are limited to using C++11, your best option is use to platform dependent API calls surrounded by appropriate preprocessor macros.

#if  defined(_WINDOWS)
// Use Windows specific APIs
#elif defined(_Linux)
// Use Linux specific APIs
#elif defined(_MacOS) ???
// Use MacOS specific APIs
#endif

More info:

For Windows: How do you check if a directory exists on Windows in C?
For Linux: Checking if a directory exists in Unix (system call)

R Sahu
  • 204,454
  • 14
  • 159
  • 270