How to create a file only if it doesn't exist

Viewed 265

In C, I can call open with O_CREAT and O_EXCL to create a new file if and only if there isn't currently one by that name. I haven't been able to find a way to do that in Haskell. I would prefer something friendly that provides a Handle, ideally with all the tricky exception handling done for me. (I don't necessarily expect it to be done for me correctly, but that's another story.)

1 Answers

I think this isn’t available directly in base, but you can use openFd from the unix package, setting the exclusive flag in the OpenFileFlags record to True. Summary:

openFd
  path
  WriteOnly
  (Just defaultMode)
  defaultFileFlags { exclusive = True }

The result of this can be converted to a normal Haskell I/O Handle using fdToHandle. If it fails, it should throw an IOError exception, which (I think) you can test with isAlreadyExistsError.

On Windows, this can be done with createFile from the Win32 package.

createFile
  path
  gENERIC_WRITE
  fILE_SHARE_NONE
  Nothing
  cREATE_NEW
  fILE_ATTRIBUTE_NORMAL
  Nothing

You can then use hANDLEToHandle to get a regular Handle. I’m not sure how the error handling works here; you may need to check the HANDLE against nullPtr and call getLastError to get error info.

Related