Kik*_*dez 5 haskell lazy-evaluation conduit
我正在使用 amazonka 流式传输 S3 文件的下载,并使用该sinkBody功能继续流式传输。目前,我下载的文件如下:
getFile bucketName fileName = do
resp <- send (getObject (BucketName bucketName) fileName)
sinkBody (resp ^. gorsBody) sinkLazy
Run Code Online (Sandbox Code Playgroud)
在哪里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
Run Code Online (Sandbox Code Playgroud)
但这段代码有一个缺陷,我需要“实现”内存中的所有惰性字节串,这意味着它无法在常量空间中运行。
有什么方法可以将管道用于yield惰性字节串并将其保存到常量内存中的文件中吗?
或者,任何其他不使用sinkLazy并解决保存到在恒定空间中运行的文件的问题的方法?
编辑
我还测试了将惰性字节流直接写入文件,如下所示,但这会消耗内存中文件大小的大约 2 倍。(writeFile来自Data.ByteString.Lazy)。
bytestream <- liftIO $ AWS.runResourceT $ runAwsT awsEnv $ getFile serviceBucket key
writeFile filename bytestream
Run Code Online (Sandbox Code Playgroud)
好吧,像这样的流式库的目的conduit是实现延迟数据结构和操作(延迟ByteString、延迟 I/O 等)的一些好处,同时更好地控制内存使用。该sinkLazy函数的目的是通过良好控制的内存占用将数据从生态系统中取出conduit,并返回到具有相关空间泄漏的惰性对象的狂野西部。所以,这就是你的问题所在。
您可能希望保留数据并将流直接放入conduit文件中,而不是使用诸如. 我没有启动并运行 AWS 测试程序,但以下类型检查可能会执行您想要的操作:ByteStringconduitsinkFile
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
211 次 |
| 最近记录: |