How to create a file and its parent directories in Haskell?
Asked Answered
F

1

8

I want to write content to a file by a non-trivial path and create all parent directories if they don't exist. So the following code:

mkFile "foo/bar/baz/quux.txt"

will create all directories foo/, foo/bar/ and foo/bar/baz/ if they don't exist (and the file quux.txt as well of course). What is the easiest way to implement such a function? Ideally, I would like to see a solution that uses only directory and filepath libraries.

Ferula answered 3/11, 2019 at 16:42 Comment(2)
Have you seen createDirectoryIfMissing? It does all the directory creation you ask for then you just need to write "" to your file (catching any exceptions as you see fit).Candie
Yes, I have seen. This function doesn't do what is required. createDirectoryIfMissing True "foo/bar.txt" creates two directories and not one directory and one file.Ferula
N
16

I'm trying to find the easiest way for this but can't find any. The only way is to implement our own function based on your needs. Fortunately, this is using System.Directory and System.FilePath.Posix libraries only.

import Prelude

import System.Directory (createDirectoryIfMissing)
import System.FilePath.Posix (takeDirectory)

main :: IO ()
main = createAndWriteFile "foo/bar/baz/quux.txt" "something"

createAndWriteFile :: FilePath -> String -> IO ()
createAndWriteFile path content = do
  createDirectoryIfMissing True $ takeDirectory path

  writeFile path content

Below is the result based on the code above.

foo
└── bar
    └── baz
        └── quux.txt

You may edit the code however you like.

Novercal answered 4/11, 2019 at 0:49 Comment(1)
Thanks, it works! It's also excellent that it works on files like foo.txt because takeDirectory returns . and createDirectoryIfMissing does nothing in such cases. I haven't tested it on Windows, but since I'm on Linux, this works for me.Ferula

© 2022 - 2024 — McMap. All rights reserved.