When is it okay to check if a file exists?

前端 未结 18 2194
再見小時候
再見小時候 2020-11-28 06:52

File systems are volatile. This means that you can\'t trust the result of one operation to still be valid for the next one, even if it\'s the next line of code. You can\'t

相关标签:
18条回答
  • 2020-11-28 07:02

    It depends on your requirements, but one way is to try to obtain an exclusive open file handle, with some sort of retry mechanism. Once you have that handle, it's going to be hard (or impossible) for another process to delete (or move) that file.

    I've used code in .NET similiar to the following to obtain an exclusive file handle, where I expect some other process to be possibly writing the file:

    FileInfo fi = new FileInfo(fullFilePath);
    
    int attempts = maxAttempts;
    do
    {
        try
        {
            // Asking to open for reading with exclusive access...
            fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.None);
        }
        // Ignore any errors... 
        catch {}
    
        if (fs != null)
        {
            break;
        }
        else
        {
            Thread.Sleep(100);
        }
    }
    while (--attempts > 0);
    
    0 讨论(0)
  • 2020-11-28 07:04

    While this is a language-agnostic post, it seems you are talking about .NET. Most systems (.NET and others) have more detailed APIs in order to figure out if the file exists when opening the file.

    What you should do is make a call to access the file, as it will typically indicate through some sort of error that the file doesn't exist (if it truly doesn't). In .NET, you would have to go through the P/Invoke layer and use the CreateFile API function. If that function returns an error of ERROR_FILE_NOT_FOUND, then you know that the file does not exist. If it returns successfully, then you have a handle that you can use.

    The point here is that it is a somewhat atomic operation, which ultimately is what you are looking for.

    Then, with the handle, you can pass it to a FileStream constructor and perform your work on the file.

    0 讨论(0)
  • 2020-11-28 07:08

    This may be too simplistic, but I would think the primary reason for checking for the existence of a file (hence the existence of .Exists()) would be to prevent unintended overwrites of existing files, not to avoid exceptions caused by attempting to access non-existent nor non-accessible files.

    EDIT 2

    This was, in fact, too simplistic and I recommend you see Stephen Martin's response.

    0 讨论(0)
  • 2020-11-28 07:11

    A variety of apps include built-in web servers. It's common for them to generate self-signed SSL certificates the first time they start up. A straightforward way to implement this would be to check whether the cert exists on startup, and create it if not.

    In theory, it could exist for the check, and not exist later. In that case, we'd get an error when we try to listen, but that can be handled quite easily and is not a big deal.

    It's also possible that it doesn't exist for the check, and exists later. In that case, it either gets overwritten with a new cert, or writing the new cert fails, depending on your policy. The first is a little annoying, in terms of the cert change causing some alarm, but also not really critical, especially if you do a bit of logging to indicate what is going on.

    And, in practice, both cases are extraordinarily unlikely to ever come up.

    0 讨论(0)
  • 2020-11-28 07:13

    I think the check makes sense when you want to be sure the file was there in the first place. As you said settings files...if there is a file I will try and merge the existing settings instead of blowing them away.

    Other cases would be when a user tells me to do something with a file. Yes I know the openFileDialog will check if a file exists (But this is optional). I vaguely remeber back in VB6 this was not the case, so verifying the file existed that they just told me to use was common.

    I'd rather not program by exception.

    Edit

    I didn't miss the point. You might try and access the file, an exception is thrown and then when you go to create the file, the file was already placed there. Which now causes your exception handling code to go on the fritz. So I guess we could then have an exception handler in our exception handler to catch that the file changed yet again...

    I'd rather try and prevent exceptions, not use them to control logic.

    Edit

    Additionally another time to check for attributes such as size is when your waiting for a file operation to finish, yes you never know for sure but with a good algorithim and depending on the system writting the file you might be able to handle a good deal of cases (Had a system running for five years which watched for small files coming over ftp, and it uses a the same api as the file system watcher, and then starts polling waiting for the file to stop changing, before raising an event that the file is ready to be consumed).

    0 讨论(0)
  • 2020-11-28 07:17

    I think anytime that you know that the file may or may not exist and you want to perform some alternate action based on the existence of the file, you should do the check because in this case it's not an exceptional condition for the file to not exist. This won't absolve you from having to handle exceptions -- from someone else either removing or creating the file between the check and your open -- but it makes the intent of the program clear and doesn't rely on exception handling to perform flow-control logic.

    EDIT: An example might be log rotation on start up.

      try
      {
           if (File.Exists("app.log"))
           {
               RotateLogs();
           }
    
           log = File.Open("app.log", FileMode.CreateNew );
      }
      catch (IOException)
      {
         ...another writer, perhaps?
      }
      catch (UnauthorizedAccessException)
      {
         ...maybe I should have used runas?
      }
    
    0 讨论(0)
提交回复
热议问题