我开发了一个应用程序,它通过具有给定偏移量的块来从Internet借用数据。出于测试目的,我有一个转储文件,其中包含每行与单独块相对应的行。我想从url和dump文件中概括读取操作。目前,我有以下功能:
getChunk :: DataSourceMode -> Config -> Int -> Int -> IO FetchResult
getChunk DSNormal config ownerId' offset' = do ...
getChunk DSFromFile config ownerId' offset' = do ...
当前实现的问题是它在每个getChunk调用上读取转储文件,显然它是无效的。第一个想法是将转储文件中的行保存到列表中,但是使用url的读数来概括它并不容易。我想,导管或管道可用于构建块的来源,但我不熟悉这些库;我应该使用其中之一,或者,是否有更好的解决方案?
答案 0 :(得分:4)
我最终得到了管道。使用广义函数 processFeed 作为接收器,然后根据模式从postUrlSource或Data.Conduit.Binary.sourceFile推送到数据中。
import Data.Conduit.Binary as CB(sourceFile, conduitFile, lines)
processFeed :: MonadIO m => Config -> OwnerId -> (OwnerId -> [Post] -> IO ()) -> Sink BS.ByteString m FetchResult
processFeed config ownerId' processFn = do ...
postUrlSource :: MonadIO m => Config -> OwnerId -> Source (StateT FetchState (m)) BS.ByteString
postUrlSource config ownerId' = do ...
...
_ <- case (dsMode config) of
DSFromFile -> do
runResourceT $ CB.sourceFile dumpFile $= CB.lines $$ (processFeed config publicId' saveResult)
DSNormal -> do
let postsFromUrlConduit = (postUrlSource config publicId') $$ (processFeed config publicId' saveResult)
fetchedPosts <- runStateT postsFromUrlConduit (FetchState 0 "")
return $ fst fetchedPosts
...
StateT用于从url获取数据的情况,因此,每个chunk都使用新的偏移量获取。 为了从文件中读取它的IO monad,它只是从转储中顺序读取行。