我正在使用aeson
/attoparsec
和conduit
/ conduit-http
connected byconduit-attoparsec
来解析来自文件 / 网络服务器的 JSON 数据。我的问题是我的管道总是抛出这个异常......
ParseError {errorContexts = ["demandInput"], errorMessage = "not enough bytes", errorPosition = 1:1}
...一旦套接字关闭或我们点击 EOF。通过管道等解析和传递生成的数据结构工作得很好,但它总是以sinkParser
抛出这个异常结束。我这样调用它...
j <- CA.sinkParser json
...在我的管道内部,将 ByteStrings 解析为我的消息结构。
一旦没有更多数据(没有更多顶级表达式),我怎样才能让它干净地退出管道?是否有任何体面的方法来检测/区分此异常而无需查看错误字符串?
谢谢!
编辑:示例:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Applicative
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8
import qualified Data.Conduit.Attoparsec as CA
import Data.Aeson
import Data.Conduit
import Data.Conduit.Binary
import Control.Monad.IO.Class
data MyMessage = MyMessage String deriving (Show)
parseMessage :: (MonadIO m, MonadResource m) => Conduit B.ByteString m B.ByteString
parseMessage = do
j <- CA.sinkParser json
let msg = fromJSON j :: Result MyMessage
yield $ case msg of
Success r -> B8.pack $ show r
Error s -> error s
parseMessage
main :: IO ()
main =
runResourceT $ do
sourceFile "./input.json" $$ parseMessage =$ sinkFile "./out.txt"
instance FromJSON MyMessage where
parseJSON j =
case j of
(Object o) -> MyMessage <$> o .: "text"
_ -> fail $ "Expected Object - " ++ show j
示例输入(input.json):
{"text":"abc"}
{"text":"123"}
输出:
out: ParseError {errorContexts = ["demandInput"], errorMessage = "not enough bytes", errorPosition = 3:1}
和 out.txt:
MyMessage "abc"MyMessage "123"