我有這個功能懶洋洋地看一個日誌文件,日誌文件中的行...消費懶洋洋的(連續)批次
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