2

Let's say I have a program that takes paths to the input and output directories from a command line. If the output directory doesn't exist, our program needs to create it. I would like to check (preferably using std::filesystem) if that path is valid, before sending it to std::filesystem::create_directory().

What is the best way to do it?

ante.ceperic
  • 263
  • 2
  • 9
  • Will the *parent* path exist? Or do directories have to be created recursively? – Some programmer dude Apr 12 '22 at 08:52
  • 6
    why not just call `create_directory` and if it suceeds then the path was valid. If not you can inspect the exception – 463035818_is_not_an_ai Apr 12 '22 at 08:52
  • What is the difference between "valid" and "exists"? – molbdnilo Apr 12 '22 at 08:54
  • And how will the path be constructed? Will it be input by a user? How? Through a directory-selection dialog (which could make sure the path exists and is valid)? From text input (in which case you need to resolve it into an absolute path yourself)? Will the parent path be fixed, and the user only inputs the later parts of the path? – Some programmer dude Apr 12 '22 at 08:55
  • 4
    Between checking and using the path the underlying filesystem may change making any validity test invalid. Just use the path to create the directory and deal with any errors. You would have to do this anyway because of the above race condition. – Richard Critten Apr 12 '22 at 09:04
  • The best way is to use `std::filesystem::create_directory()` , check for error and act accordingly. There are basically three possible outcomes: (a) the directory has been created correctly, (b) the directory already exists, (c) the directory could not be created. In cases (a) and (b) you basically just write onto the directory afterwards, but be aware that in case (b) you might not have write access to the directory, but you'll find that out as soon as you try to write into it. – Jabberwocky Apr 12 '22 at 09:21

3 Answers3

3

You gain nothing by doing (pseudo-code alert):

if (doesnt_exist(dir)) {
    create_directory(dir);
}

Better to just do:

create_directory(dir);

And handle errors properly if necessary. You may not even need to handle errors here if you handle subsequent errors.

The "if exists" check introduces unnecessary complexity, and introduces a race condition. And even if the directory doesn't exist, you may still not have permission to create it. So in any case your error handling will be the same, rendering the "if exists" check completely pointless.

I guess it's another way of "don't ask permission, ask forgiveness" except with computers you don't need to ask forgiveness.

tenfour
  • 36,141
  • 15
  • 83
  • 142
1

Only way to know for sure it to try to use the path. Even if the path is in a correct format or exists in the filesystem, you might not be able to use it.

Some examples of technically valid paths that you cannot use:

  • It is in the personal directory of another user, but you have no permission to write or even read it
  • It is a file that exists, so you cannot create the same path as a directory
  • It is on a removable disk that cannot be written on
  • It is on a network computer that is not connected at the moment
  • It is a web path, but the domain name is not in use
VLL
  • 9,634
  • 1
  • 29
  • 54
1

The exists() function checks for that.

std::string my_path = "my_folder_path";
if(!std::filesystem::exists(my_path)) {
  std::filesystem::create_directory(my_path);
}
Michael
  • 878
  • 5
  • 17