sourcecode:
|
module System.Directory
( doesFileExist, doesDirectoryExist, getFileSize, getModificationTime
, getCurrentDirectory, setCurrentDirectory
, getDirectoryContents, createDirectory, createDirectoryIfMissing
, removeDirectory, renameDirectory
, getHomeDirectory, getTemporaryDirectory
, getAbsolutePath
, removeFile, renameFile, copyFile
, findFileWithSuffix, getFileWithSuffix
) where
import System.FilePath ( FilePath, (</>), splitDirectories, isAbsolute
, normalise, pathSeparator, searchPathSeparator)
import System.Environment ( getEnv, isWindows )
import Data.List ( isPrefixOf, scanl1, last, intersperse )
import Data.Time ( ClockTime )
--- Returns true if the argument is the name of an existing file.
doesFileExist :: FilePath -> IO Bool
doesFileExist fname = prim_doesFileExist $## fname
prim_doesFileExist :: FilePath -> IO Bool
prim_doesFileExist external
--- Returns true if the argument is the name of an existing directory.
doesDirectoryExist :: FilePath -> IO Bool
doesDirectoryExist dir = prim_doesDirectoryExist $## dir
prim_doesDirectoryExist :: FilePath -> IO Bool
prim_doesDirectoryExist external
--- Returns the size of the file.
getFileSize :: FilePath -> IO Int
getFileSize fname = prim_fileSize $## fname
prim_fileSize :: FilePath -> IO Int
prim_fileSize external
--- Returns the modification time of the file.
getModificationTime :: FilePath -> IO ClockTime
getModificationTime fname = prim_getModificationTime $## fname
prim_getModificationTime :: FilePath -> IO ClockTime
prim_getModificationTime external
--- Returns the current working directory.
getCurrentDirectory :: IO FilePath
getCurrentDirectory external
--- Sets the current working directory.
setCurrentDirectory :: FilePath -> IO ()
setCurrentDirectory dir = prim_setCurrentDirectory $## dir
prim_setCurrentDirectory :: FilePath -> IO ()
prim_setCurrentDirectory external
--- Returns the list of all entries in a directory.
getDirectoryContents :: FilePath -> IO [FilePath]
getDirectoryContents dir = prim_getDirectoryContents $## dir
prim_getDirectoryContents :: FilePath -> IO [FilePath]
prim_getDirectoryContents external
--- Creates a new directory with the given name.
createDirectory :: FilePath -> IO ()
createDirectory dir = prim_createDirectory $## dir
prim_createDirectory :: FilePath -> IO ()
prim_createDirectory external
--- Creates a new directory with the given name if it does not already exist.
--- If the first parameter is `True` it will also create all missing
--- parent directories.
createDirectoryIfMissing :: Bool -> FilePath -> IO ()
createDirectoryIfMissing createParents path
= if createParents then createDirs parents
else createDirs [last parents]
where
parents = scanl1 (</>) $ splitDirectories $ path
createDirs [] = return ()
createDirs (d:ds) = do
exists <- doesDirectoryExist d
if exists then return () else createDirectory d
createDirs ds
--- Deletes a directory from the file system.
removeDirectory :: FilePath -> IO ()
removeDirectory dir = prim_removeDirectory $## dir
prim_removeDirectory :: FilePath -> IO ()
prim_removeDirectory external
--- Renames a directory.
renameDirectory :: FilePath -> FilePath -> IO ()
renameDirectory dir1 dir2 = (prim_renameDirectory $## dir1) $## dir2
prim_renameDirectory :: FilePath -> FilePath -> IO ()
prim_renameDirectory external
--- Returns the home directory of the current user.
getHomeDirectory :: IO FilePath
getHomeDirectory = if isWindows
then getEnv "USERPROFILE"
else getEnv "HOME"
--- Returns the temporary directory of the operating system.
getTemporaryDirectory :: IO FilePath
getTemporaryDirectory = if isWindows then getEnv "TMP" else return "/tmp"
--- Convert a path name into an absolute one.
--- For instance, a leading `~` is replaced by the current home directory.
getAbsolutePath :: FilePath -> IO FilePath
getAbsolutePath path
| isAbsolute path = return (normalise path)
| path == "~" = getHomeDirectory
| "~/" `isPrefixOf` path = do homedir <- getHomeDirectory
return (normalise (homedir </> drop 2 path))
| otherwise = do curdir <- getCurrentDirectory
return (normalise (curdir </> path))
--- Deletes a file from the file system.
removeFile :: FilePath -> IO ()
removeFile file = prim_removeFile $## file
prim_removeFile :: FilePath -> IO ()
prim_removeFile external
--- Renames a file.
renameFile :: FilePath -> FilePath -> IO ()
renameFile file1 file2 = (prim_renameFile $## file1) $## file2
prim_renameFile :: FilePath -> FilePath -> IO ()
prim_renameFile external
--- Copy the contents from one file to another file
copyFile :: FilePath -> FilePath -> IO ()
copyFile src dest = readFile src >>= writeFile dest
--- Looks up the first file with a possible suffix in a list of directories.
--- Returns Nothing if such a file does not exist.
findFileWithSuffix :: String -> [String] -> [String] -> IO (Maybe String)
findFileWithSuffix file suffixes path =
if isAbsolute file
then lookupFirstFileWithSuffix file suffixes
else lookupFirstFile path
where
lookupFirstFile [] = return Nothing
lookupFirstFile (dir:dirs) = do
mbfile <- lookupFirstFileWithSuffix (dir++pathSeparator:file) suffixes
maybe (lookupFirstFile dirs) (return . Just) mbfile
lookupFirstFileWithSuffix _ [] = return Nothing
lookupFirstFileWithSuffix f (suf:sufs) = do
let fsuf = f++suf
exfile <- doesFileExist fsuf
if exfile then return (Just fsuf)
else lookupFirstFileWithSuffix f sufs
--- Gets the first file with a possible suffix in a list of directories.
--- An error message is delivered if there is no such file.
getFileWithSuffix :: String -> [String] -> [String] -> IO String
getFileWithSuffix file suffixes path = do
mbfile <- findFileWithSuffix file suffixes path
maybe (error $ "File "++file++" not found in path "++
concat (intersperse [searchPathSeparator] path))
return
mbfile
|