我正在使用 amazonka 流式傳輸 S3 檔案的下載,并使用該sinkBody功能繼續流式傳輸。目前,我下載檔案如下:
getFile bucketName fileName = do
resp <- send (getObject (BucketName bucketName) fileName)
sinkBody (resp ^. gorsBody) sinkLazy
哪里sinkBody :: MonadIO m => RsBody -> ConduitM ByteString Void (ResourceT IO) a -> m a。為了在恒定記憶體中運行,我認為這sinkLazy是從管道流中獲取值的好選擇。
在此之后,我想將資料的惰性位元組串(S3 檔案)保存到本地檔案中,為此我使用以下代碼:
-- fetch stream of data from S3
bytestream <- liftIO $ AWS.runResourceT $ runAwsT awsEnv $ getFile serviceBucket key
-- create a file
liftIO $ writeFile filePath ""
-- write content of stream into the file (strict version), keeps data in memory...
liftIO $ runConduitRes $ yield bytestream .| mapC B.toStrict .| sinkFile filePath
但是這段代碼有一個缺陷,我需要“實作”記憶體中所有的惰性位元組串,這意味著它不能在恒定空間中運行。
有什么方法可以將管道用于
yield惰性位元組串并將其保存到常量記憶體中的檔案中嗎?或者,任何其他不使用
sinkLazy并且解決保存到在恒定空間中運行的檔案的問題的方法?
編輯
我還測驗了將惰性位元組流直接寫入檔案,如下所示,但這會消耗大約 2 倍的記憶體檔案大小。(writeFile來自Data.ByteString.Lazy)。
bytestream <- liftIO $ AWS.runResourceT $ runAwsT awsEnv $ getFile serviceBucket key
writeFile filename bytestream
uj5u.com熱心網友回復:
嗯,流庫的目的conduit是實作惰性資料結構和操作(惰性ByteStrings、惰性 I/O 等)的一些好處,同時更好地控制記憶體使用。該sinkLazy函式的目的是將資料conduit從其良好控制的記憶體占用的生態系統中取出,并回傳到具有相關空間泄漏的惰性物件的狂野西部。所以,這就是你的問題。
而不是沉流出來conduit,進入一個懶惰的ByteString,你可能想保留的資料conduit,并直接沉流進該檔案,使用類似sinkFile。我沒有啟動并運行 AWS 測驗程式,但以下型別檢查可能會執行您想要的操作:
import Conduit
import Control.Lens
import Network.AWS
import Network.AWS.S3
getFile bucketName fileName outputFileName = do
resp <- send (getObject (BucketName bucketName) fileName)
sinkBody (resp ^. gorsBody) (sinkFile outputFileName)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/339381.html
下一篇:Haskell字串/輸出操作
