File 通过管道传输整个文件
我正在努力通过Servant下载(动态)文件 假设我有以下函数,用于使用此库从S3中提取文件: 输出到磁盘的文件是完全正确的(33KB)PDF文件(可以打开该文件)File 通过管道传输整个文件,file,haskell,streaming,conduit,File,Haskell,Streaming,Conduit,我正在努力通过Servant下载(动态)文件 假设我有以下函数,用于使用此库从S3中提取文件: 输出到磁盘的文件是完全正确的(33KB)PDF文件(可以打开该文件) 我的问题是,我在哪里丢失了文件的其余部分?我是不是用错了导管?我该如何解决这个问题。为什么有人否决了这个问题并投票决定结束它?FWIW,在进一步调查缩小范围后,我编辑了这个问题problem@AbrahamPawait只等待单个块。与sinkFile不同,它在源代码耗尽之前不会一直读取。要将所有传入的strictByteString
我的问题是,我在哪里丢失了文件的其余部分?我是不是用错了导管?我该如何解决这个问题。为什么有人否决了这个问题并投票决定结束它?FWIW,在进一步调查缩小范围后,我编辑了这个问题problem@AbrahamP
await
只等待单个块。与sinkFile
不同,它在源代码耗尽之前不会一直读取。要将所有传入的strictByteString
s累积到一个lazyByteString
,请尝试sinkdlazy
。但是,如果文件是在读取时写入的,那么内存使用情况会更好,就像您在|sinkFile./tmp/foo.pdf“
中所做的那样。(在sinkFile
之后的| wait
看起来没有必要,因为sinkFile
不会在下游产生任何结果。)
getS3Object
:: MonadIO m
=> MonadReader Config m
=> MonadError CustomError m
=> Text
-> m (Maybe ByteString)
getS3Object fileName = do
config <- ask
configObject <- constructS3Authentication
mgr <- liftIO $ newManager tlsManagerSettings
liftIO $ runResourceT $
Aws.pureAws (awsConfig configObject) (s3Config configObject) mgr (S3.getObject (config ^. awsCustomerDocumentsBucket) fileName) >>=
\gor -> runConduit (responseBody (S3.gorResponse gor) .| await)
fetchDocument
:: MonadIO m
=> MonadCatch m
=> MonadReader Config m
=> MonadError CustomError m
=> NewDocumentInput
-> m ByteString
fetchDocument inputDocument = do
let fileName = computeFileName inputDocument
documentObject <- getS3Object fileName
case documentObject of
Nothing -> throwError $ OtherAWSError "No document returned, or other uncaught exception"
Just document -> liftIO $ do
writeFile "./tmp/potato.pdf" document
return document
\gor -> runConduit (responseBody (S3.gorResponse gor) .| sinkFile "./tmp/foo.pdf" .| await)