Copyright | © 2016 Julian Ospald |
---|---|
License | BSD3 |
Maintainer | Julian Ospald <hasufell@posteo.de> |
Stability | experimental |
Portability | portable |
Safe Haskell | Safe |
Language | Haskell2010 |
The equivalent of System.FilePath on raw (byte string) file paths.
Not all functions of System.FilePath are implemented yet. Feel free to contribute!
- pathSeparator :: Word8
- isPathSeparator :: Word8 -> Bool
- searchPathSeparator :: Word8
- isSearchPathSeparator :: Word8 -> Bool
- extSeparator :: Word8
- isExtSeparator :: Word8 -> Bool
- splitSearchPath :: ByteString -> [RawFilePath]
- getSearchPath :: IO [RawFilePath]
- splitExtension :: RawFilePath -> (RawFilePath, ByteString)
- takeExtension :: RawFilePath -> ByteString
- replaceExtension :: RawFilePath -> ByteString -> RawFilePath
- dropExtension :: RawFilePath -> RawFilePath
- addExtension :: RawFilePath -> ByteString -> RawFilePath
- hasExtension :: RawFilePath -> Bool
- (<.>) :: RawFilePath -> ByteString -> RawFilePath
- splitExtensions :: RawFilePath -> (RawFilePath, ByteString)
- dropExtensions :: RawFilePath -> RawFilePath
- takeExtensions :: RawFilePath -> ByteString
- stripExtension :: ByteString -> RawFilePath -> Maybe RawFilePath
- splitFileName :: RawFilePath -> (RawFilePath, RawFilePath)
- takeFileName :: RawFilePath -> RawFilePath
- replaceFileName :: RawFilePath -> ByteString -> RawFilePath
- dropFileName :: RawFilePath -> RawFilePath
- takeBaseName :: RawFilePath -> ByteString
- replaceBaseName :: RawFilePath -> ByteString -> RawFilePath
- takeDirectory :: RawFilePath -> RawFilePath
- replaceDirectory :: RawFilePath -> ByteString -> RawFilePath
- combine :: RawFilePath -> RawFilePath -> RawFilePath
- (</>) :: RawFilePath -> RawFilePath -> RawFilePath
- splitPath :: RawFilePath -> [RawFilePath]
- joinPath :: [RawFilePath] -> RawFilePath
- splitDirectories :: RawFilePath -> [RawFilePath]
- hasTrailingPathSeparator :: RawFilePath -> Bool
- addTrailingPathSeparator :: RawFilePath -> RawFilePath
- dropTrailingPathSeparator :: RawFilePath -> RawFilePath
- normalise :: RawFilePath -> RawFilePath
- makeRelative :: RawFilePath -> RawFilePath -> RawFilePath
- equalFilePath :: RawFilePath -> RawFilePath -> Bool
- isRelative :: RawFilePath -> Bool
- isAbsolute :: RawFilePath -> Bool
- isValid :: RawFilePath -> Bool
- makeValid :: RawFilePath -> RawFilePath
- isFileName :: RawFilePath -> Bool
- hasParentDir :: RawFilePath -> Bool
- hiddenFile :: RawFilePath -> Bool
- module System.Posix.ByteString.FilePath
Separator predicates
Path separator character
isPathSeparator :: Word8 -> Bool Source
Check if a character is the path separator
\n -> (_chr n == '/') == isPathSeparator n
searchPathSeparator :: Word8 Source
Search path separator
isSearchPathSeparator :: Word8 -> Bool Source
Check if a character is the search path separator
\n -> (_chr n == ':') == isSearchPathSeparator n
File extension separator
isExtSeparator :: Word8 -> Bool Source
Check if a character is the file extension separator
\n -> (_chr n == '.') == isExtSeparator n
$PATH methods
splitSearchPath :: ByteString -> [RawFilePath] Source
Take a ByteString, split it on the searchPathSeparator
.
Blank items are converted to .
.
Follows the recommendations in http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
>>>
splitSearchPath "File1:File2:File3"
["File1","File2","File3"]>>>
splitSearchPath "File1::File2:File3"
["File1",".","File2","File3"]>>>
splitSearchPath ""
["."]
getSearchPath :: IO [RawFilePath] Source
Get a list of RawFilePath
s in the $PATH variable.
Extension functions
splitExtension :: RawFilePath -> (RawFilePath, ByteString) Source
Split a RawFilePath
into a path+filename and extension
>>>
splitExtension "file.exe"
("file",".exe")>>>
splitExtension "file"
("file","")>>>
splitExtension "/path/file.tar.gz"
("/path/file.tar",".gz")
\path -> uncurry (BS.append) (splitExtension path) == path
takeExtension :: RawFilePath -> ByteString Source
Get the final extension from a RawFilePath
>>>
takeExtension "file.exe"
".exe">>>
takeExtension "file"
"">>>
takeExtension "/path/file.tar.gz"
".gz"
replaceExtension :: RawFilePath -> ByteString -> RawFilePath Source
Change a file's extension
\path -> let ext = takeExtension path in replaceExtension path ext == path
dropExtension :: RawFilePath -> RawFilePath Source
Drop the final extension from a RawFilePath
>>>
dropExtension "file.exe"
"file">>>
dropExtension "file"
"file">>>
dropExtension "/path/file.tar.gz"
"/path/file.tar"
addExtension :: RawFilePath -> ByteString -> RawFilePath Source
Add an extension to a RawFilePath
>>>
addExtension "file" ".exe"
"file.exe">>>
addExtension "file.tar" ".gz"
"file.tar.gz">>>
addExtension "/path/" ".ext"
"/path/.ext"
hasExtension :: RawFilePath -> Bool Source
Check if a RawFilePath
has an extension
>>>
hasExtension "file"
False>>>
hasExtension "file.tar"
True>>>
hasExtension "/path.part1/"
False
(<.>) :: RawFilePath -> ByteString -> RawFilePath Source
Operator version of addExtension
splitExtensions :: RawFilePath -> (RawFilePath, ByteString) Source
Split a RawFilePath
on the first extension.
>>>
splitExtensions "/path/file.tar.gz"
("/path/file",".tar.gz")
\path -> uncurry addExtension (splitExtensions path) == path
dropExtensions :: RawFilePath -> RawFilePath Source
Remove all extensions from a RawFilePath
>>>
dropExtensions "/path/file.tar.gz"
"/path/file"
takeExtensions :: RawFilePath -> ByteString Source
Take all extensions from a RawFilePath
>>>
takeExtensions "/path/file.tar.gz"
".tar.gz"
stripExtension :: ByteString -> RawFilePath -> Maybe RawFilePath Source
Drop the given extension from a FilePath, and the "."
preceding it.
Returns Nothing
if the FilePath does not have the given extension, or
Just
and the part before the extension if it does.
This function can be more predictable than dropExtensions
,
especially if the filename might itself contain .
characters.
>>>
stripExtension "hs.o" "foo.x.hs.o"
Just "foo.x">>>
stripExtension "hi.o" "foo.x.hs.o"
Nothing>>>
stripExtension ".c.d" "a.b.c.d"
Just "a.b">>>
stripExtension ".c.d" "a.b..c.d"
Just "a.b.">>>
stripExtension "baz" "foo.bar"
Nothing>>>
stripExtension "bar" "foobar"
Nothing
\path -> stripExtension "" path == Just path
\path -> dropExtension path == fromJust (stripExtension (takeExtension path) path)
\path -> dropExtensions path == fromJust (stripExtension (takeExtensions path) path)
Filename/directory functions
splitFileName :: RawFilePath -> (RawFilePath, RawFilePath) Source
Split a RawFilePath
into (path,file). combine
is the inverse
>>>
splitFileName "path/file.txt"
("path/","file.txt")>>>
splitFileName "path/"
("path/","")>>>
splitFileName "file.txt"
("./","file.txt")
\path -> uncurry combine (splitFileName path) == path || fst (splitFileName path) == "./"
takeFileName :: RawFilePath -> RawFilePath Source
Get the file name
>>>
takeFileName "path/file.txt"
"file.txt">>>
takeFileName "path/"
""
replaceFileName :: RawFilePath -> ByteString -> RawFilePath Source
Change the file name
\path -> replaceFileName path (takeFileName path) == path
dropFileName :: RawFilePath -> RawFilePath Source
Drop the file name
>>>
dropFileName "path/file.txt"
"path/">>>
dropFileName "file.txt"
"./"
takeBaseName :: RawFilePath -> ByteString Source
Get the file name, without a trailing extension
>>>
takeBaseName "path/file.tar.gz"
"file.tar">>>
takeBaseName ""
""
replaceBaseName :: RawFilePath -> ByteString -> RawFilePath Source
Change the base name
>>>
replaceBaseName "path/file.tar.gz" "bob"
"path/bob.gz"
\path -> replaceBaseName path (takeBaseName path) == path
takeDirectory :: RawFilePath -> RawFilePath Source
Get the directory, moving up one level if it's already a directory
>>>
takeDirectory "path/file.txt"
"path">>>
takeDirectory "file"
".">>>
takeDirectory "/path/to/"
"/path/to">>>
takeDirectory "/path/to"
"/path"
replaceDirectory :: RawFilePath -> ByteString -> RawFilePath Source
Change the directory component of a RawFilePath
\path -> replaceDirectory path (takeDirectory path) `equalFilePath` path || takeDirectory path == "."
combine :: RawFilePath -> RawFilePath -> RawFilePath Source
Join two paths together
>>>
combine "/" "file"
"/file">>>
combine "/path/to" "file"
"/path/to/file">>>
combine "file" "/absolute/path"
"/absolute/path"
(</>) :: RawFilePath -> RawFilePath -> RawFilePath Source
Operator version of combine
splitPath :: RawFilePath -> [RawFilePath] Source
Split a path into a list of components:
>>>
splitPath "/path/to/file.txt"
["/","path/","to/","file.txt"]
\path -> BS.concat (splitPath path) == path
joinPath :: [RawFilePath] -> RawFilePath Source
Join a split path back together
\path -> joinPath (splitPath path) == path
>>>
joinPath ["path","to","file.txt"]
"path/to/file.txt"
splitDirectories :: RawFilePath -> [RawFilePath] Source
Like splitPath
, but without trailing slashes
>>>
splitDirectories "/path/to/file.txt"
["/","path","to","file.txt"]>>>
splitDirectories ""
[]
Trailing slash functions
hasTrailingPathSeparator :: RawFilePath -> Bool Source
Check if the last character of a RawFilePath
is /
.
>>>
hasTrailingPathSeparator "/path/"
True>>>
hasTrailingPathSeparator "/"
True>>>
hasTrailingPathSeparator "/path"
False
addTrailingPathSeparator :: RawFilePath -> RawFilePath Source
Add a trailing path separator.
>>>
addTrailingPathSeparator "/path"
"/path/">>>
addTrailingPathSeparator "/path/"
"/path/">>>
addTrailingPathSeparator "/"
"/"
dropTrailingPathSeparator :: RawFilePath -> RawFilePath Source
Remove a trailing path separator
>>>
dropTrailingPathSeparator "/path/"
"/path">>>
dropTrailingPathSeparator "/path////"
"/path">>>
dropTrailingPathSeparator "/"
"/">>>
dropTrailingPathSeparator "//"
"/"
File name manipulations
normalise :: RawFilePath -> RawFilePath Source
Normalise a file.
>>>
normalise "/file/\\test////"
"/file/\\test/">>>
normalise "/file/./test"
"/file/test">>>
normalise "/test/file/../bob/fred/"
"/test/file/../bob/fred/">>>
normalise "../bob/fred/"
"../bob/fred/">>>
normalise "./bob/fred/"
"bob/fred/">>>
normalise "./bob////.fred/./...///./..///#."
"bob/.fred/.../../#.">>>
normalise "."
".">>>
normalise "./"
"./">>>
normalise "./."
"./">>>
normalise "/./"
"/">>>
normalise "/"
"/">>>
normalise "bob/fred/."
"bob/fred/">>>
normalise "//home"
"/home"
makeRelative :: RawFilePath -> RawFilePath -> RawFilePath Source
Contract a filename, based on a relative path. Note that the resulting
path will never introduce ..
paths, as the presence of symlinks
means ../b
may not reach a/b
if it starts from a/c
. For a
worked example see
this blog post.
>>>
makeRelative "/directory" "/directory/file.ext"
"file.ext">>>
makeRelative "/Home" "/home/bob"
"/home/bob">>>
makeRelative "/home/" "/home/bob/foo/bar"
"bob/foo/bar">>>
makeRelative "/fred" "bob"
"bob">>>
makeRelative "/file/test" "/file/test/fred"
"fred">>>
makeRelative "/file/test" "/file/test/fred/"
"fred/">>>
makeRelative "some/path" "some/path/a/b/c"
"a/b/c"
\p -> makeRelative p p == "."
\p -> makeRelative (takeDirectory p) p `equalFilePath` takeFileName p
prop x y -> equalFilePath x y || (isRelative x && makeRelative y x == x) || equalFilePath (y / makeRelative y x) x
equalFilePath :: RawFilePath -> RawFilePath -> Bool Source
Equality of two filepaths. The filepaths are normalised and trailing path separators are dropped.
>>>
equalFilePath "foo" "foo"
True>>>
equalFilePath "foo" "foo/"
True>>>
equalFilePath "foo" "./foo"
True>>>
equalFilePath "" ""
True>>>
equalFilePath "foo" "/foo"
False>>>
equalFilePath "foo" "FOO"
False>>>
equalFilePath "foo" "../foo"
False
\p -> equalFilePath p p
isRelative :: RawFilePath -> Bool Source
Check if a path is relative
\path -> isRelative path /= isAbsolute path
isAbsolute :: RawFilePath -> Bool Source
Check if a path is absolute
>>>
isAbsolute "/path"
True>>>
isAbsolute "path"
False>>>
isAbsolute ""
False
isValid :: RawFilePath -> Bool Source
Is a FilePath valid, i.e. could you create a file like it?
>>>
isValid ""
False>>>
isValid "\0"
False>>>
isValid "/random_ path:*"
True
makeValid :: RawFilePath -> RawFilePath Source
Take a FilePath and make it valid; does not change already valid FilePaths.
>>>
makeValid ""
"_">>>
makeValid "file\0name"
"file_name"
\p -> if isValid p then makeValid p == p else makeValid p /= p
\p -> isValid (makeValid p)
isFileName :: RawFilePath -> Bool Source
Is the given path a valid filename? This includes "." and "..".
>>>
isFileName "lal"
True>>>
isFileName "."
True>>>
isFileName ".."
True>>>
isFileName ""
False>>>
isFileName "\0"
False>>>
isFileName "/random_ path:*"
False
hasParentDir :: RawFilePath -> Bool Source
Check if the filepath has any parent directories in it.
>>>
hasParentDir "/.."
True>>>
hasParentDir "foo/bar/.."
True>>>
hasParentDir "foo/../bar/."
True>>>
hasParentDir "foo/bar"
False>>>
hasParentDir "foo"
False>>>
hasParentDir ""
False>>>
hasParentDir ".."
False
hiddenFile :: RawFilePath -> Bool Source
Whether the file is a hidden file.
>>>
hiddenFile ".foo"
True>>>
hiddenFile "..foo.bar"
True>>>
hiddenFile "some/path/.bar"
True>>>
hiddenFile "..."
True>>>
hiddenFile "dod.bar"
False>>>
hiddenFile "."
False>>>
hiddenFile ".."
False>>>
hiddenFile ""
False