What to use these days for file path handling?

What library should I use these days for file path handling in a new project?

The project is small and I only need to take filepaths from the command line (via Options.Applicative), check for the existence of the filepath, read the content from a filepath and write content to a filepaths.

Should I use the new-fangled OsPath or rather stick to the standard FilePath?

Thanks for pointers!

2 Likes

System.IO right now doesn’t have OsPath support, so you’ll have to convert back to FilePath anyway to read the file.

Also it seems like hardcoding strings is only possible with quasiquoters, no direct unsafe functions.

1 Like

I would use the new OsPath (and I already did in some of my projects). You can read files using the functions in the accompanying file-io: Basic file IO operations via 'OsPath' package so no need to convert back to FilePath manually.

So far the only thing I missed and had to convert manually was the “getDataFileName” functions from “Paths_” that cabal generates.

5 Likes

In our production code we use path everywhere; it provides safe defaults and protection against path traversal attacks due to explicitly typing Abs/Rel and Dir/File.

We use path-io for most operations, and call toFilePath :: Path b t -> FilePath when passing a path to a FilePath-accepting function.

2 Likes

I wrote the OsPath layer.

If you can, try to use it. Here’s the blog post explaining it: 2022-06-29-fixing-haskell-filepaths · Hasufell's blog

Some core libraries already support it: directory, unix and Win32 all do.

optparse-applicative does not. I’ve done some work towards that goal: bytestring parser · Issue #65 · pcapriotti/optparse-applicative · GitHub

So what I’m trying to do now is provide the complete text/bytestring API for OsString. That will require splitting out a new package os-string or so, because it really doesn’t belong in filepath anymore:

That’s all non-trivial work and I’ve been sick a lot lately.


Wrt path library: I don’t believe in it, because it tries to shove the file vs dir distinction into the type level. But that’s more of a runtime property of filepaths than anything else. So I created hpath, which also has its own io package etc., because I was dissatisfied with base and directory. However, I haven’t found the time to migrate it to OsPath either. Right now it only supports unix and is ByteString based, unlike path (which still uses FilePath).

12 Likes

Thank you all for your comments. Much appreciated for me as a beginner!

I might go withe old-school file handling for now, because the current project is rather light on the file handling side plus optparse-applicative doesn’t support OsPath yet.