dfコマンドを作ってみました
http://valkyrja.ddo.jp/~raito/hiki/?2006-10-10#Windows%CD%D1df%A5%B3%A5%DE%A5%F3%A5%C9を読んで、Haskellでdfコマンドを作成してみました。ラッキーなことに必要なWin32APIはGHCに標準で入っていました。単位はメガバイトで出力するようにしました(端数は切り捨て)。桁が大きくなると見にくいので、3桁ずつカンマで区切るようにしました。
ファイル: df.hs
module Main (main) where import Control.Monad (filterM) import Data.Bits (testBit) import System.Win32.File (getLogicalDrives, getDiskFreeSpace) import System.Win32.Types (DWORD) import Text.Printf (printf) getLogicalDriveStrs :: IO [String] getLogicalDriveStrs = do drives <- getLogicalDrives filterM (return . not . null) $ zipWith (f drives) [0 .. 25] driveStrs where driveStrs = map (: ":\\") ['A' .. 'Z'] f drives i s | testBit drives i = s | otherwise = "" getDiskFreeSpacesNoErr :: [String] -> IO [(String, (DWORD, DWORD, DWORD, DWORD))] getDiskFreeSpacesNoErr ds = filterErr =<< mapM (catchErr . getDiskFreeSpace') ds where getDiskFreeSpace' d = do dfs <- getDiskFreeSpace $ Just d return (d, dfs) catchErr f = catch f (\ e -> return ("", (0, 0, 0, 0))) filterErr = filterM (return . (/= ("", (0, 0, 0, 0)))) format :: (String, (DWORD, DWORD, DWORD, DWORD)) -> String format (d, ds) = let free = toMega $ freeSpaceBytes ds total = toMega $ totalSpaceBytes ds used = toMega $ (totalSpaceBytes ds - freeSpaceBytes ds) percent = (totalSpaceBytes ds - freeSpaceBytes ds) * 100 `div` totalSpaceBytes ds in printf "%-12s %12s %12s %12s %4d%%" d (comma total) (comma used) (comma free) percent where freeSpaceBytes (sectPerClust, bytesPerSect, nFreeClust, nTotalClust) = (toInteger nFreeClust) * (toInteger (sectPerClust * bytesPerSect)) totalSpaceBytes (sectPerClust, bytesPerSect, nFreeClust, nTotalClust) = (toInteger nTotalClust) * (toInteger (sectPerClust * bytesPerSect)) toMega n = n `div` (1024 * 1024) comma n = tail . reverse $ f $ reverse $ show n where f [] = "" f s = let (s1, s2) = splitAt 3 s in s1 ++ "," ++ f s2 main :: IO () main = do printf "%-12s %12s %12s %12s %4s\n" "Filesystem" "Total" "Used" "Available" "Used%" mapM_ putStrLn . map format =<< getDiskFreeSpacesNoErr =<< getLogicalDriveStrs
実行例:
$ ./df.exe Filesystem Total Used Available Used% C:\ 20,475 15,256 5,219 74% E:\ 21,426 16,326 5,099 76% F:\ 5,076 4,592 484 90%