File 通过管道传输整个文件

File 通过管道传输整个文件,file,haskell,streaming,conduit,File,Haskell,Streaming,Conduit,我正在努力通过Servant下载(动态)文件 假设我有以下函数,用于使用此库从S3中提取文件: 输出到磁盘的文件是完全正确的(33KB)PDF文件(可以打开该文件) 我的问题是,我在哪里丢失了文件的其余部分?我是不是用错了导管?我该如何解决这个问题。为什么有人否决了这个问题并投票决定结束它?FWIW,在进一步调查缩小范围后,我编辑了这个问题problem@AbrahamPawait只等待单个块。与sinkFile不同,它在源代码耗尽之前不会一直读取。要将所有传入的strictByteString

我正在努力通过Servant下载(动态)文件

假设我有以下函数,用于使用此库从S3中提取文件:

输出到磁盘的文件是完全正确的(33KB)PDF文件(可以打开该文件)


我的问题是,我在哪里丢失了文件的其余部分?我是不是用错了导管?我该如何解决这个问题。

为什么有人否决了这个问题并投票决定结束它?FWIW,在进一步调查缩小范围后,我编辑了这个问题problem@AbrahamP
await
只等待单个块。与
sinkFile
不同,它在源代码耗尽之前不会一直读取。要将所有传入的strict
ByteString
s累积到一个lazy
ByteString
,请尝试
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)