我有这个功能懒洋洋地看一个日志文件,日志文件中的行...消费懒洋洋的(连续)批次
follow :: Handle -> IO [String]
follow h = unsafeInterleaveIO $ do
catch (do line <- hGetLine h
lines <- follow h
return $ line : lines)
(const (do threadDelay (1000 * 100)
follow h))
...这是伟大的,因为它返回它可以处理线的无限列表如下所示:
h <- openFile "test.log" ReadMode
ls <- follow h
mapM_ putStrLn ls
但是现在我需要在处理它们之前一起连接一些行。 (有些日志条目是xml分割成多行,我需要将它们放在一起)。我尝试了以下方法来做到这一点,但它永远不会终止,因为follow
从来没有这样做,据我所知。
h <- openFile "test.log" ReadMode
ls <- follow h
mapM_ putStrLn (concatWhen (isPrefixOf "foo") ls)
concatWhen :: (String -> Bool) -> [String] -> [String]
concatWhen _ [] = []
concatWhen p as = let (xs, as') = span p as
(ys, rest) = break p as'
in (concat xs) : ys ++ (concatWhen p rest)
是否有这样做的一个好办法吗?我是否需要在follow
之内进行连接,还是有更好的方法可以对该函数返回的字符串数组进行操作?
如果有差异,可以通过检查内容来确定一行是否是需要连接的组的最后一行。
顺便提一下这个问题,懒惰IO这样有很多问题(主要涉及资源分配),一般应该避免。 – ehird