开发者

Faster alternatives to hFileSize to retrieve the size of a file in Haskell?

开发者 https://www.devze.com 2023-02-23 07:08 出处:网络
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:

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
0

精彩评论

暂无评论...
验证码 换一张
取 消