| ||||||||
| ||||||||
| ||||||||
Description | ||||||||
This is the current interface for System.FilePath, please import it as System.FilePath.Version_0_10 - do not use System.FilePath directly. The next version is currently under development, and I have used used 3 codes to indicate what will happen to each method (although they are still useable now):
A library for FilePath manipulations, designed to be cross platform. This library will select the correct type of FilePath's for the platform the code is running on at runtime. For more details see http://www.cs.york.ac.uk/~ndm/projects/libraries.php Some short examples: You are given a C file, you want to figure out the corresponding object (.o) file: replaceExtension file "o" Haskell module Main imports Test, you have the file named main: [replaceFileName path_to_main "Test" <.> ext | ext <- ["hs","lhs"] ] You want to download a file from the web and save it to disk: do let file = makeValid url System.IO.createDirectoryIfMissing True (takeDirectory file) You want to compile a Haskell file, but put the hi file under "interface" takeDirectory file </> "interface" </> (takeFileName file `replaceExtension` "hi") You want to display a filename to the user, as neatly as possible shortPath file >>= putStrLn The examples in code format descibed by each function are used to generate tests, and should give clear semantics for the functions. | ||||||||
Synopsis | ||||||||
The basic functions | ||||||||
pathSeparator :: Char | ||||||||
The character that separates directories. In the case where more than one character is possible, pathSeparator is the ideal one. Windows: pathSeparator == '\\' Posix: pathSeparator == '/' isPathSeparator pathSeparator | ||||||||
pathSeparators :: [Char] | ||||||||
The list of all possible separators. Windows: pathSeparators == ['\\', '/'] Posix: pathSeparators == ['/'] pathSeparator `elem` pathSeparators | ||||||||
isPathSeparator :: Char -> Bool | ||||||||
Rather than using (== pathSeparator), use this. Test if something is a path separator. isPathSeparator a == (a `elem` pathSeparators) | ||||||||
fileSeparator :: Char | ||||||||
RENAMED - searchPathSeparator. A list of possible file separators, between the $PATH variable Windows: fileSeparator == ';' Posix: fileSeparator == ':' | ||||||||
isFileSeparator :: Char -> Bool | ||||||||
RENAMED - isSearchPathSeparator. Is the character a file separator? isFileSeparator a == (a == fileSeparator) | ||||||||
extSeparator :: Char | ||||||||
File extension character extSeparator == '.' | ||||||||
isExtSeparator :: Char -> Bool | ||||||||
Is the character an extension character? isExtSeparator a == (a == extSeparator) | ||||||||
Path methods (environment $PATH) | ||||||||
splitFiles :: String -> [FilePath] | ||||||||
RENAMED - splitSearchPath. Take a string, split it on the fileSeparators character. Windows: splitFiles "File1;File2;File3" == ["File1","File2","File3"] Posix: splitFiles "File1:File2:File3" == ["File1","File2","File3"] | ||||||||
getSearchPath :: IO [FilePath] | ||||||||
Get a list of filepaths in the $PATH. | ||||||||
Extension methods | ||||||||
splitExtension :: FilePath -> (String, String) | ||||||||
Split on the extension. addExtension is the inverse. uncurry (++) (splitExtension x) == x uncurry addExtension (splitExtension x) == x splitExtension "file.txt" == ("file",".txt") splitExtension "file" == ("file","") splitExtension "file/file.txt" == ("file/file",".txt") splitExtension "file.txt/boris" == ("file.txt/boris","") splitExtension "file.txt/boris.ext" == ("file.txt/boris",".ext") splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred") splitExtension "file/path.txt/" == ("file/path.txt/","") | ||||||||
takeExtension :: FilePath -> String | ||||||||
Get the extension of a file, returns "" for no extension, .ext otherwise. takeExtension x == snd (splitExtension x) takeExtension (addExtension x "ext") == ".ext" takeExtension (replaceExtension x "ext") == ".ext" | ||||||||
replaceExtension :: FilePath -> String -> FilePath | ||||||||
Set the extension of a file, overwriting one if already present. replaceExtension "file.txt" ".bob" == "file.bob" replaceExtension "file.txt" "bob" == "file.bob" replaceExtension "file" ".bob" == "file.bob" replaceExtension "file.txt" "" == "file" replaceExtension "file.fred.bob" "txt" == "file.fred.txt" | ||||||||
dropExtension :: FilePath -> FilePath | ||||||||
Remove last extension, and any . following it. dropExtension x == fst (splitExtension x) | ||||||||
addExtension :: FilePath -> String -> FilePath | ||||||||
Add an extension, even if there is already one there. E.g. addExtension "foo.txt" "bat" -> "foo.txt.bat". addExtension "file.txt" "bib" == "file.txt.bib" addExtension "file." ".bib" == "file..bib" addExtension "file" ".bib" == "file.bib" Windows: addExtension "\\\\share" ".txt" == "\\\\share\\.txt" | ||||||||
hasExtension :: FilePath -> Bool | ||||||||
Does the given filename have an extension? null (takeExtension x) == not (hasExtension x) | ||||||||
(<.>) :: FilePath -> String -> FilePath | ||||||||
Alias to addExtension, for people who like that sort of thing. | ||||||||
splitExtensions :: FilePath -> (FilePath, String) | ||||||||
Split on all extensions splitExtensions "file.tar.gz" == ("file",".tar.gz") | ||||||||
dropExtensions :: FilePath -> FilePath | ||||||||
Drop all extensions not $ hasExtension (dropExtensions x) | ||||||||
takeExtensions :: FilePath -> String | ||||||||
Get all extensions | ||||||||
Operations on a filepath, as a list of directories | ||||||||
splitFileName :: FilePath -> (String, String) | ||||||||
Split a filename into directory and file. addFileName is the inverse. uncurry (++) (splitFileName x) == x uncurry addFileName (splitFileName x) == x splitFileName "file/bob.txt" == ("file/", "bob.txt") splitFileName "file/" == ("file/", "") splitFileName "bob" == ("", "bob") Posix: splitFileName "/" == ("/","") Windows: splitFileName "c:" == ("c:","") | ||||||||
takeFileName :: FilePath -> FilePath | ||||||||
Get the file name. takeFileName "test/" == "" takeFileName x == snd (splitFileName x) takeFileName (replaceFileName x "fred") == "fred" takeFileName (addFileName x "fred") == "fred" | ||||||||
replaceFileName :: FilePath -> String -> FilePath | ||||||||
Set the filename. replaceFileName x (takeFileName x) == x | ||||||||
dropFileName :: FilePath -> FilePath | ||||||||
Drop the filename. dropFileName x == fst (splitFileName x) | ||||||||
addFileName :: FilePath -> String -> FilePath | ||||||||
GONE - use combine. Add a filename onto the end of a path. addFileName (takeDirectory x) (takeFileName x) `equalFilePath` x | ||||||||
takeBaseName :: FilePath -> String | ||||||||
Get the base name, without an extension or path. takeBaseName "file/test.txt" == "test" takeBaseName "dave.ext" == "dave" | ||||||||
replaceBaseName :: FilePath -> String -> FilePath | ||||||||
Set the base name. replaceBaseName "file/test.txt" "bob" == "file/bob.txt" replaceBaseName "fred" "bill" == "bill" replaceBaseName "/dave/fred/bob.gz.tar" "new" == "/dave/fred/new.tar" replaceBaseName x (takeBaseName x) == x | ||||||||
takeDirectory :: FilePath -> FilePath | ||||||||
Get the directory name, move up one level. Posix: takeDirectory "/foo/bar/baz" == "/foo/bar" Posix: takeDirectory "/foo/bar/baz/" == "/foo/bar/baz" | ||||||||
replaceDirectory :: FilePath -> String -> FilePath | ||||||||
Set the directory, keeping the filename the same. replaceDirectory x (takeDirectory x) `equalFilePath` x | ||||||||
isDirectory :: FilePath -> Bool | ||||||||
Is an item either a directory or the last character a path separator? This does not query the file system. isDirectory "test" == False isDirectory "test/" == True | ||||||||
isFile :: FilePath -> Bool | ||||||||
Is an item a file, does not query the file system. isDirectory x == not (isFile x) | ||||||||
asDirectory :: FilePath -> FilePath | ||||||||
Make something look like a directory isDirectory (asDirectory x) if isDirectory x then asDirectory x == x else True Posix: asDirectory "test/rest" == "test/rest/" | ||||||||
asFile :: FilePath -> FilePath | ||||||||
Make something look like a file asFile "file/test/" == "file/test" not (isDirectory (asFile x)) || isDrive x Posix: asFile "/" == "/" | ||||||||
combine :: FilePath -> FilePath -> FilePath | ||||||||
Combine two paths, if the second path isAbsolute, then it returns the second. Posix: combine "/" "test" == "/test" Posix: combine "home" "bob" == "home/bob" Windows: combine "home" "bob" == "home\\bob" | ||||||||
(</>) :: FilePath -> FilePath -> FilePath | ||||||||
A nice alias for combine. | ||||||||
splitPath :: FilePath -> [FilePath] | ||||||||
Split a path by the directory separator. concat (splitPath x) == x splitPath "test//item/" == ["test//","item/"] splitPath "test/item/file" == ["test/","item/","file"] splitPath "" == [] Windows: splitPath "c:\\test\\path" == ["c:\\","test\\","path"] Posix: splitPath "/file/test" == ["/","file/","test"] | ||||||||
joinPath :: [FilePath] -> FilePath | ||||||||
Join path elements back together. joinPath (splitPath (makeValid x)) == makeValid x | ||||||||
splitDirectories :: FilePath -> [FilePath] | ||||||||
Just as splitPath, but don't add the trailing slashes to each element. splitDirectories "test/file" == ["test","file"] splitDirectories "/test/file" == ["/","test","file"] joinPath (splitDirectories (makeValid x)) `equalFilePath` makeValid x splitDirectories "" == [] | ||||||||
File name manipulators | ||||||||
normalise :: FilePath -> FilePath | ||||||||
Normalise a file
Posix: normalise "/file/\\test////" == "/file/\\test/" Posix: normalise "/file/./test" == "/file/test" Posix: normalise "/test/file/../bob/fred/" == "/test/file/../bob/fred/" Posix: normalise "../bob/fred/" == "../bob/fred/" Posix: normalise "./bob/fred/" == "bob/fred/" Windows: normalise "c:\\file/bob\\" == "C:\\file\\bob\\" Windows: normalise "\\\\server\\test" == "\\\\server\\test" Windows: normalise "c:/file" == "C:\\file" | ||||||||
equalFilePath :: FilePath -> FilePath -> Bool | ||||||||
Equality of two FilePaths. If you call System.Directory.canonicalizePath first this has a much better chance of working. Note that this doesn't follow symlinks or DOSNAM~1s. | ||||||||
shortPath :: FilePath -> IO FilePath | ||||||||
RENAMED - makeRelativeToCurrentDirectory. shortPathWith the current directory. | ||||||||
shortPathWith :: FilePath -> FilePath -> FilePath | ||||||||
RENAMED - makeRelative. Contract a filename, based on a relative path. Posix: shortPathWith "/home/" "/home/bob/foo/bar" == "bob/foo/bar" Posix: shortPathWith "/fred" "bob" == "bob" Posix: shortPathWith "/file/test" "/file/test/fred" == "fred" Posix: shortPathWith "/file/test" "/file/test/fred/" == "fred/" Posix: shortPathWith "/fred/dave" "/fred/bill" == "../bill" | ||||||||
isValid :: FilePath -> Bool | ||||||||
Is a FilePath valid, i.e. could you create a file like it? Posix: isValid "/random_ path:*" == True Posix: isValid x == True Windows: isValid "c:\\test" == True Windows: isValid "c:\\test:of_test" == False Windows: isValid "test*" == False Windows: isValid "c:\\test\\nul" == False Windows: isValid "c:\\test\\prn.txt" == False Windows: isValid "c:\\nul\\file" == False | ||||||||
Produced by Haddock version 0.8 |