I am wondering how to get the size of a file in haskell开发者_Go百科 with the least amount of overhead. Right now I have the following code:
getFileSize :: FilePath -> IO Integer
getFileSize x = do
handle <- openFile x ReadMode
size <- hFileSize handle
hClose handle
return size
This seems to be quite slow. I have stumbled across getFileStatus in System.Posix.Files but don't know how it works - at least I only get errors when playing around with it in ghci. Also, I am not sure if this would work on Windows (probably not).
So to reiterate: What is the best (and platform independent) approach to get the size of a file in Haskell?
What you want are indeed getFileStatus
and fileSize
, both from System.Posix
(which will work just fine under Windows, if you use the unix-compat package instead of unix
). Usage is as follows, leaving error handling up to you:
getFileSize :: String -> IO Integer
getFileSize path = do
stat <- getFileStatus path
return $ fromIntegral (fileSize stat)
For what it's worth, and though I think it's less readable, you could shorten this form to:
getFileSize path = getFileStatus path >>= \s -> return $ fileSize s
I don't know if there is a better way. RWH supplies its own wrapper to hFileSize:
getFileSize path = handle (\_ -> return Nothing) $
bracket (openFile path ReadMode) hClose $ \h -> do
size <- hFileSize h
return (Just size)
It also notes that the unix-compat is available, which "provides portable implementations of parts of the unix package."
It seems like System.Posix.Files doesn't work in Windows (except in Cygwin), have you tried unix-compat ?
https://hackage.haskell.org/package/unix-compat-0.4.1.4/docs/System-PosixCompat-Files.html
This worked for me on my Windows 10 machine:
> cabal install unix-compat
Resolving dependencies...
... lots of output, plus I had to put Cygwin on my path to make it build ...
> ghci
Prelude> import System.PosixCompat.Files
Prelude System.PosixCompat.Files> getFileStatus ".bashrc">>= \s -> return $ fileSize s
5764
import System.Posix.Files
import System.Posix.Types
getFileSize :: FilePath -> IO FileOffset
getFileSize path = fmap fileSize $ getFileStatus path
https://hackage.haskell.org/package/directory-1.3.6.0/docs/System-Directory.html#v:getFileSize
getFileSize :: FilePath -> IO Integer
精彩评论