簡體   English   中英

當長度已知時,從Lazy ByteString構造RequestBodyStream

[英]Constructing RequestBodyStream from Lazy ByteString when length is known

我正在嘗試修改此AWS S3上傳代碼以處理長度已知的Lazy ByteString (這樣就不會強制在內存中完整讀取它-它是通過​​網絡預先發送長度的)。 看來我必須在Lazy ByteString上定義GivesPopper函數,以將其轉換為RequestBodyStream 由於定義了GivesPopper的復雜方式,因此我不確定如何為Lazy ByteString編寫它。 將不勝感激如何編寫它的指針。 這里是它是如何從文件中讀取寫入:

let file ="test"
-- streams large file content, without buffering more than 10k in memory
let streamer sink = withFile file ReadMode $ \h -> sink $ S.hGet h 10240

如果我正確理解,上面代碼中的streamer GivesPopper ()類型為GivesPopper () 給定一個長度為lenLazy ByteString ,在上面編寫GivesPopper函數的一種好方法是什么? 我們一次可以讀取一個塊。

這是您要找的東西嗎?

import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as L
import System.IO

file = "test"
-- original streamer for feeding a sink from a file
streamer :: (IO S.ByteString -> IO r) -> IO r
streamer sink = withFile file ReadMode $ \h -> sink $ S.hGet h 10240

-- feed a lazy ByteString to sink    
lstreamer :: L.ByteString -> (IO S.ByteString -> IO r) -> IO r
lstreamer lbs sink = sink (return (L.toStrict lbs))

lstreamer類型檢查,但可能並沒有完全按照您想要的做。 每次接收器調用時,它僅返回相同的數據。 另一方面, S.hGet h ...最終將返回空字符串。

這是一個使用IORef來跟蹤是否應該開始返回空字符串的解決方案:

import Data.IORef

mklstream :: L.ByteString -> (IO S.ByteString -> IO r) -> IO r
mklstream lbs sink = do
  ref <- newIORef False
  let fetch :: IO S.ByteString
      fetch = do sent <- readIORef ref
                 writeIORef ref True
                 if sent
                   then return S.empty
                   else return (L.toStrict lbs)
  sink fetch

這里fetch是獲取一個塊的動作。 第一次調用它,您將獲得原始的惰性Bytestring(嚴格限制)。 后續調用將始終返回空字符串。

更新

一次發放少量款項的方法如下:

mklstream :: L.ByteString -> (IO S.ByteString -> IO r) -> IO r
mklstream lbs sink = do
  ref <- newIORef (L.toChunks lbs)
  let fetch :: IO S.ByteString
      fetch = do chunks <- readIORef ref
                 case chunks of
                   [] -> return S.empty
                   (c:cs) -> do writeIORef ref cs
                                return c
  sink fetch

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM