Random tools I've written for myself and I could not think of anywhere else to put them.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

39 lines
1.5 KiB

import System.Directory
import System.Posix.Files
import System.FilePath
import Control.Monad
import Control.Exception
du :: Monad m
=> (String -> m Integer) -- ^ Get size of some file
-> (String -> m ([String], [String])) -- ^ Get (files, subdirectories) of some directory
-> String -- ^ Root path
-> m Integer
du sizeof lsdir = loop where
loop path = do
(files, subdirs) <- lsdir path
filesizes <- mapM sizeof files
dirsizes <- mapM loop subdirs
return $! sum $ filesizes ++ dirsizes
-- | 'du' for the filesystem
duIO :: String -> IO Integer
duIO = du sizeof lsdir where
sizeof path = do
status <- getFileStatus path
return . toInteger . fileSize $ status
lsdir dir = do
contents <- getDirectoryContents dir
let valid n = not (elem n [".", ".."])
stats <- forM (filter valid contents) $ \name -> do
let path = dir </> name
handle (\(SomeException _) -> return Nothing) $ do
status <- getFileStatus path
return $ Just (path, status)
let directories = [p | Just (p, stat) <- stats, isDirectory stat]
let files = [p | Just (p, stat) <- stats, isRegularFile stat]
return (files, directories)
main = do
size <- duIO "/home/craige/Documents"
putStrLn $ "size = " ++ show size