Haskell 流式下载
Haskell streaming download
我发现的两个资源是:
- https://haskell-lang.org/library/http-client#Streaming
- http://www.alfredodinapoli.com/posts/2013-07-20-slick-http-download-in-haskell.html
我如何修改前者中的代码以 (a) 保存到文件,以及 (b) 只打印一个(取 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 个),并向我建议我仍然不明白 monads 或 liftIO 上的映射是如何工作的。
此外,此资源:
http://haskelliseasy.readthedocs.io/en/latest/#note-on-streaming
...给我一个警告,"I know what I'm doing and I'd like more fine-grained control over resources, such as streaming" 这不容易或通常不支持。
我看过的其他地方:
- Downloading large files from the Internet in Haskell
- https://hackage.haskell.org/package/wreq
- https://hackage.haskell.org/package/pipes-http
如果 Haskell 节中有任何内容可以使这更容易,更像是 Python 的请求:
response = requests.get(URL, stream=True)
for i,chunk in enumerate(response.iter_content(BLOCK)):
f.write(chunk)
我也很感激那里的提示,或者指向 2016 年最先进技术的指示。
您可能正在从最新版本的 http-conduit
中寻找 httpSource
。它的行为与 Python 的请求非常相似:你得到一个块流。
save to file
这很简单,只需将源直接重定向到文件接收器即可。
#!/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"
print only a (take 5) of the byte response
获得源后,我们使用 takeCE 5
获取前 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
save to file and print only a (take 5) of the byte response
为此,您需要 zipSinks
or, for more general cases that involve zipping multiple sinks 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")
我发现的两个资源是:
- https://haskell-lang.org/library/http-client#Streaming
- http://www.alfredodinapoli.com/posts/2013-07-20-slick-http-download-in-haskell.html
我如何修改前者中的代码以 (a) 保存到文件,以及 (b) 只打印一个(取 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 个),并向我建议我仍然不明白 monads 或 liftIO 上的映射是如何工作的。
此外,此资源:
http://haskelliseasy.readthedocs.io/en/latest/#note-on-streaming
...给我一个警告,"I know what I'm doing and I'd like more fine-grained control over resources, such as streaming" 这不容易或通常不支持。
我看过的其他地方:
- Downloading large files from the Internet in Haskell
- https://hackage.haskell.org/package/wreq
- https://hackage.haskell.org/package/pipes-http
如果 Haskell 节中有任何内容可以使这更容易,更像是 Python 的请求:
response = requests.get(URL, stream=True)
for i,chunk in enumerate(response.iter_content(BLOCK)):
f.write(chunk)
我也很感激那里的提示,或者指向 2016 年最先进技术的指示。
您可能正在从最新版本的 http-conduit
中寻找 httpSource
。它的行为与 Python 的请求非常相似:你得到一个块流。
save to file
这很简单,只需将源直接重定向到文件接收器即可。
#!/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"
print only a (take 5) of the byte response
获得源后,我们使用 takeCE 5
获取前 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
save to file and print only a (take 5) of the byte response
为此,您需要 zipSinks
or, for more general cases that involve zipping multiple sinks 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")