Haskell流下载

Mit*_*ops 4 haskell conduit

我发现使用流行的Haskell库进行流式下载的两个建议方法是:

我将如何修改前者中的代码以(a)保存到文件,并且(b)仅打印(取5个)字节响应,而不是对stdout的整个响应?

我对(b)的尝试是:

#!/usr/bin/env stack
{- stack --install-ghc --resolver lts-5.13 runghc
   --package http-conduit
 -}
{-# LANGUAGE OverloadedStrings #-}
import           Control.Monad.IO.Class (liftIO)
import qualified Data.ByteString        as S
import qualified Data.Conduit.List      as CL
import           Network.HTTP.Simple
import           System.IO              (stdout)

main :: IO ()
main = httpSink "http://httpbin.org/get" $ \response -> do
    liftIO $ putStrLn
           $ "The status code was: "
          ++ show (getResponseStatusCode response)

    CL.mapM_ (take 5) (S.hPut stdout)
Run Code Online (Sandbox Code Playgroud)

它无法映射(取5),并向我提出了很多建议,但我仍然不了解在monads上进行映射或liftIO是如何工作的。

另外,此资源:

http://haskelliseasy.readthedocs.io/en/latest/#note-on-streaming

…向我发出警告,“我知道我在做什么,我想对资源(例如流媒体)进行更细粒度的控制”,这是不容易或通常不支持的。

我看过的其他地方:

如果Haskellverse中有什么可以简化此过程,更像Python的请求:

response = requests.get(URL, stream=True)
for i,chunk in enumerate(response.iter_content(BLOCK)):
  f.write(chunk)
Run Code Online (Sandbox Code Playgroud)

我也很乐意那里的技巧或指向2016年最新技术的指针。

Ale*_*lec 5

您可能正在httpSource从的最新版本中寻找http-conduit。它的行为几乎与Python的请求完全一样:您将获得大量的数据块。

保存到文件

这很容易,只需将源直接重定向到文件接收器即可。

#!/usr/bin/env stack
{- stack --install-ghc --resolver nightly-2016-11-26 runghc --package http-conduit -}

{-# LANGUAGE OverloadedStrings #-}
import Network.HTTP.Simple (httpSource, getResponseBody)
import Conduit

main = runConduitRes $ httpSource "http://httpbin.org/get" getResponseBody
                    .| sinkFile "data_file"
Run Code Online (Sandbox Code Playgroud)

仅打印(取5)字节响应

有了源代码后,我们将使用前5个字节,takeCE 5然后通过打印这些字节printC

#!/usr/bin/env stack
{- stack --install-ghc --resolver nightly-2016-11-26 runghc --package http-conduit -}

{-# LANGUAGE OverloadedStrings #-}
import Network.HTTP.Simple (httpSource, getResponseBody)
import Data.ByteString (unpack)
import Conduit

main = runConduitRes $ httpSource "http://httpbin.org/get" getResponseBody
                    .| takeCE 5
                    .| printC
Run Code Online (Sandbox Code Playgroud)

保存到文件仅打印(取5)字节响应

为此,您需要,zipSinks或者对于涉及压缩多个接收器的更一般的情况ZipSink

#!/usr/bin/env stack
{- stack --install-ghc --resolver nightly-2016-11-26 runghc --package http-conduit -}

{-# LANGUAGE OverloadedStrings #-}
import Network.HTTP.Simple (httpSource, getResponseBody)
import Data.ByteString (unpack)
import Data.Conduit.Internal (zipSinks)
import Conduit

main = runConduitRes $ httpSource "http://httpbin.org/get" getResponseBody
                    .| zipSinks (takeCE 5 .| printC)
                                (sinkFile "data_file")
Run Code Online (Sandbox Code Playgroud)