I have really strange behavior when reading files from / proc. If I read / proc / pid / stat lazily with prelude readFile - it works, but not the way I want. Switching to strict reading with Data.ByteString.readFile gives me an empty string.
I need a rigorous reading here to be able to compare the results of two readings in a short amount of time.
So using System.IO.readFile to read / proc / pid / stat just doesn't work. This gives me the same result at 0.5 second intervals. I suppose this is due to laziness and a half-closed pen or something else ... The file descriptor opens and closes.
h <- openFile "/proc/pid/stat" ReadMode st1 <- hGetLine h; hClose h
But why above if we have a string reading bytestring. Correctly?
This is where I am stuck.
import qualified Data.ByteString as B B.readFile "/proc/pid/stat" >>= print
This always returns an empty string. Also tested at GHCI. Any suggestions. Thanks.
--- UPDATE ---
Thanks to Daniel for the suggestions.
This is what I really need to do. This can help to fully show my dilemma and provide more general suggestions.
I need to calculate process statistics. The following is part of the code (CPU usage only).
cpuUsage pid = do st1 <- readProc $ "/proc" </> pid </> "stat" threadDelay 500000 -- 0.5 sec st2 <- readProc $ "/proc" </> pid </> "stat" let sum1 = (read $ words st1 !! 13) + (read $ words st1 !! 14) sum2 = (read $ words st2 !! 13) + (read $ words st2 !! 14) return $ round $ fromIntegral (sum2 - sum1) * jiffy / delay * 100 where jiffy = 0.01 delay = 0.5 readProc f = do h <- openFile f ReadMode c <- hGetLine h hClose h return c
- Prelude.readFile not working due to laziness
- Strict functions from ByteString do not work. Thanks to Daniel for the explanation.
- withFile will work (it closes the descriptor correctly) if I fill in all the calculations in it, but then the interval will not be strictly 0.5, since the calculations will take time.
- Opening and closing handles explicitly and using hGetContents does not work! For the same reason, readFile does not.
The only thing that works in this situation is to explicitly open and close the descriptors using hGetLine in the code fragment. But this is not good enough, as some proc files have more than one line, for example / proc / meminfo.
So, I need a function that will strictly read the entire file. Something like hGetContents, but strict.
I tried to do this:
readProc f = do h <- openFile f ReadMode c <- hGetContents h let c' = lines c hClose h return c'
Hoping that the lines will call it to read the file completely. Bad luck. Anyway, get an empty list.
Any help, suggestion very much appreciated.