2016-11-28 3 views
4

2つのリソースは、私は、人気のHaskellライブラリを使用してダウンロードをストリーミングするための提案のレシピがあることがわかった:Haskellのストリーミングダウンロード

がどのように私は、元のコードを変更します(a)ファイルに保存し、(b)stdoutへの応答全体ではなく、バイト応答のうちの5つだけを出力しますか?

(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) 

(5を取る)、そしてとりわけ私に示唆して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) 

私はそこのヒントも、2016年の最先端技術を知ることができます。

+1

これは実際にストリームする必要がありますか? (だから十分に大量のデータを一度に取得しているので、メモリ内のすべてが容認できないのですか?) – Alec

+0

はい、してください。 – Mittenchops

+0

私はたぶん2^nのようなより賢明なバイト数を選択したはずです。 – Mittenchops

答えて

3

おそらく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" 

プリントのみ(5を取る)バイト応答の

我々はソースを持っていたら、私たちはtakeCE 5で最初の5つのバイトを取り、その後printCを経由してこれらを印刷してください。これを行うには、バイト応答

プリントのみ(5を取る)ファイルに保存

#!/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 

、あなたは複数のシンクをビュン伴い、より一般的なケースのため、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") 
+1

実際には、takeCEはストリームの要素、つまり5バイトを正確に取得します。 –

+0

申し訳ありませんが、まだコンデュイットとこの考え方を学んでいます。これは/ this/both/takeC5をstdoutにストリームしてファイルにシンクしますか? – Mittenchops

+1

@MichaelSnoyman Nifty。あなたの図書館を愛して! – Alec