Created
June 30, 2011 06:26
-
-
Save ijt/1055731 to your computer and use it in GitHub Desktop.
Haskell example of tailing a file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env runhaskell | |
-- Example of tailing a file, using two communicating Haskell threads. It's not | |
-- really necessary to do this concurrently, but the approach here generalizes | |
-- nicely if we want to filter or transform the output. | |
import Control.Concurrent | |
import Control.Monad | |
import System.Environment | |
import System.Exit | |
import System.IO | |
import System.Posix.Files | |
type Line = String | |
usage = "usage: tailf file" | |
main = do | |
args <- getArgs | |
case args of | |
[] -> do | |
putStrLn usage | |
exitFailure | |
["-h"] -> do | |
putStrLn usage | |
exitSuccess | |
["--help"] -> do | |
putStrLn usage | |
exitSuccess | |
[path] -> do | |
c <- newEmptyMVar | |
forkIO (getLines path 0 c) | |
forever $ do | |
msg <- takeMVar c | |
putStr msg | |
-- |getLines tails the file, sending the lines back to the caller through the | |
-- passed-in MVar. | |
getLines :: FilePath -> Integer -> MVar Line -> IO () | |
getLines path sizeSoFar mvar = do | |
stat <- getFileStatus path | |
let newSize = fromIntegral $ fileSize stat :: Integer | |
if newSize > sizeSoFar | |
then do | |
handle <- openFile path ReadMode | |
hSeek handle AbsoluteSeek sizeSoFar | |
newContents <- hGetContents handle | |
putMVar mvar newContents | |
getLines path newSize mvar | |
else do | |
getLines path sizeSoFar mvar |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A few comments. Apologies for doing so without solicitation, but I figure this could help others like me who are looking for a way to stream files in Haskell.
else
condition of getLines, it will busyloop, using 100% CPU while it continuously checks if the file has changed, until some new data has been written to the file.