从/ proc读取文件的时候,我的行为真的很奇怪如果我用前奏的readFile懒惰的读取/ proc / pid / stat – 它可以工作,但不是我想要的。 使用Data.ByteString.readFile切换到严格阅读给了我一个空string。
我需要严格的阅读才能够在短时间内比较两次读取的结果。
所以使用System.IO.readFile读取/ proc / pid / stat根本不起作用。 它在0.5秒的间隔内给了我相同的结果。 我认为这是由于懒惰和半closures句柄或什么…打开和closures文件句柄显式工作。
h <- openFile "/proc/pid/stat" ReadMode st1 <- hGetLine h; hClose h
但是,为什么上面如果我们有bytestring严格阅读。 对?
这是我卡住的地方。
import qualified Data.ByteString as B B.readFile "/proc/pid/stat" >>= print
这总是返回一个空string。 还在GHCI中进行了testing。 有什么build议么。 谢谢。
— 更新 —
谢谢丹尼尔的build议。
这是我真正需要做的。 这可能有助于充分展示我的困境,并提出更多的一般性build议。
我需要计算进程统计信息。 以下是代码的一部分(仅以CPU使用率为例)。
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
在这种情况下工作的唯一的事情是在上面的代码片段中用hGetLine明确地打开和closures句柄。 但是这不够好,因为一些proc文件比/ proc / meminfo多一行。
所以我需要一个能够严格读取整个文件的函数。 像hGetContents,但严格。
我试图这样做:
readProc f = do h <- openFile f ReadMode c <- hGetContents h let c' = lines c hClose h return c'
希望这些行会触发它读取文件。 没有运气。 仍然得到一个空的列表。
任何帮助,build议非常感激。
ByteString
代码是
readFile :: FilePath -> IO ByteString readFile f = bracket (openBinaryFile f ReadMode) hClose (\h -> hFileSize h >>= hGet h . fromIntegral)
但是/proc/whatever
不是真正的文件,它是按需生成的,当你stat
它们以获得文件大小时,你得到0.所以ByteString
的readFile
成功读取0字节。
在编写这种类型的东西之前,检查一下Hackage上已经存在的东西通常是个好主意。 在这种情况下,我发现了procstat包,这似乎很好地工作:
import System.Linux.ProcStat cpuUsage pid = do Just before <- fmap procTotalTime <$> procStat pid threadDelay 500000 -- 0.5 sec Just after <- fmap procTotalTime <$> procStat pid return . round $ fromIntegral (after - before) * jiffy / delay * 100 where procTotalTime info = procUTime info + procSTime info jiffy = 0.01 delay = 0.5