Search code examples
exceptionfile-iod

Open a File in D


If I want to safely try to open a file in D, is the preferred way to either

  1. try to open it, catch exception (and optionally figure out why) if it fails or
  2. check if it exists, is readable and only then open it

I'm guessing the second alternative results in more IO and is more complex right?


Solution

  • Generally, it's better to check whether the file exists first, because it's often very likely that the file doesn't exist, and simply letting it fail when you try and open it is a case of using exceptions for flow control. It's also inefficient in the case where the file doesn't exist, because exceptions are quite expensive in D (though the cost of the I/O may still outweigh the cost of the exception given how expensive I/O is).

    It's generally considered bad practice to use exceptions in cases where the exception is likely to be thrown. In those cases, it's far better to return whether the operation succeeded or to check whether the operation is likely to succeed prior to attempting the operation. In the case of opening files, you'd likely do the latter. So, the cleanest way to do what you're trying to do would be to do something like

    if(filename.exists)
    {
        auto file = File(filename);
        ...
    }
    

    or if you want to read the whole file in as a string in one go, you'd do

    if(filename.exists)
    {
        auto fileContents = readText(filename);
        ...
    }
    

    exists and readText are in std.file, and File is in std.stdio.

    If you're dealing with a case where it's highly likely that the file will exist and that therefore it's very unlikely that an exception will be thrown, then skipping the check and just trying to open the file is fine. But what you want to avoid is relying on the exception being thrown when it's not unlikely that the operation will fail. You want exceptions to be thrown rarely, so you check that operations will succeed before attempting them if it's likely that they will fail and throw an exception. Otherwise, you end up using exceptions for flow control and harm the efficiency (and maintainability) of your program.

    And it's often the case that a file won't be there when you try and open it, so it's usually the case that you should check that a file exists before trying to open it (but it does ultimately depend on your particular use case).