我想將給定目錄中的所有json文件解析爲數據類型結果。如何使用Data.Text.Lazy.IO與Aeson解析JSON文件
所以我有一個解碼功能
decodeResult :: Data.ByteString.Lazy.ByteString -> Maybe Result
我Data.Text.Lazy.IO開始到文件加載到懶惰的字節串,
import qualified Data.Text.Lazy.IO as T
import qualified Data.Text.Lazy.Encoding as T
getFileContent :: FilePath -> IO B.ByteString
getFileContent path = T.encodeUtf8 `fmap` T.readFile path
它編譯,但是我跑進太多文件打開的問題,所以我想也許我應該使用withFile。
import System.IO
import qualified Data.ByteString.Lazy as B
import qualified Data.Text.Lazy.IO as T
import qualified Data.Text.Lazy.Encoding as T
getFileContent :: FilePath -> IO (Maybe Result)
getFileContent path = withFile path ReadMode $ \hnd -> do
content <- T.hGetContents hnd
return $ (decodeAnalytic . T.encodeUtf8) content
loadAllResults :: FilePath -> IO [Result]
loadAllResults path = do
paths <- listDirectory path
results <- sequence $ fmap getFileContent (fmap (path ++) $ filter (endswith ".json") paths)
return $ catMaybes results
在這個版本中,懶惰的io似乎永遠不會被評估,它總是返回空列表。但如果我打印內容getFileContent函數,那麼一切似乎工作正常。
getFileContent :: FilePath -> IO (Maybe Result)
getFileContent path = withFile path ReadMode $ \hnd -> do
content <- T.hGetContents hnd
print content
return $ (decodeAnalytic . T.encodeUtf8) content
所以我不知道我錯過了什麼,我應該使用管道這種類型的東西?
簡單的答案是肯定的,使用管道或類似的東西。更復雜的答案是,你的'loadAllResults'是*令人難以置信的*懶惰 - 簡單地執行'loadAllResults x'實際上並不讀取任何文件(或者確實打開它們)。當您嘗試評估結果列表時,您同時打開所有文件並嘗試閱讀它們。 'withFile'不會幫助你,因爲懶惰來自'hGetContents' - 嘗試切換到非懶惰的Text IO。 – user2407038