从 /proc 读取文件时我的行为非常奇怪如果我用 prelude 的 readFile 懒惰地读取 /proc/pid/stat - 它可以工作,但不是我想要的方式。使用 Data.ByteString.readFile 切换到严格阅读会给我一个空字符串。
我需要在这里严格阅读,以便能够在短时间内比较两次阅读的结果。
所以使用 System.IO.readFile 读取 /proc/pid/stat 根本不起作用。它在 0.5 秒的间隔内给了我相同的结果。我认为这是由于懒惰和半封闭句柄或其他原因......打开和关闭文件句柄显式有效。
h <- openFile "/proc/pid/stat" ReadMode
st1 <- hGetLine h; hClose h
但是,如果我们有严格的字节串阅读,为什么要这样做。对?
这就是我卡住的地方。
import qualified Data.ByteString as B
B.readFile "/proc/pid/stat" >>= print
这总是返回一个空字符串。也在 GHCI 中进行了测试。有什么建议么。谢谢。
---更新---
谢谢丹尼尔的建议。
这是我真正需要做的。这可能有助于充分展示我的困境并带来更一般的建议。
我需要计算过程统计信息。这里以部分代码(只是 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
- 由于懒惰,Prelude.readFile 不起作用
- ByteString 中的严格函数不起作用。谢谢丹尼尔的解释。
- 如果我将整个计算塞入其中,withFile 将起作用(它会正确关闭句柄),但是由于计算需要时间,因此间隔不会严格为 0.5。
- 显式打开和关闭句柄并使用 hGetContents 不起作用!出于同样的原因 readFile 没有。
在这种情况下唯一有效的是在上面的代码片段中使用 hGetLine 显式打开和关闭句柄。但这还不够好,因为某些 proc 文件不止一行,例如 /proc/meminfo。
所以我需要一个可以严格读取整个文件的函数。类似于 hGetContents 但严格的东西。
我试图这样做:
readProc f = do
h <- openFile f ReadMode
c <- hGetContents h
let c' = lines c
hClose h
return c'
希望这些行会触发它完整读取文件。没运气。仍然得到一个空列表。
任何帮助,建议非常感谢。