[英]conduit http streaming to file (sinkFile) avoid file creation when http returns error
http代碼不成功並且我不希望創建文件時,需要從getSrc返回的值是什么(通過sinkFile )
如果我只返回getResponseBody res,則http錯誤本身將保存到文件中。
downloadURL :: String -> FilePath -> IO ()
downloadURL url location = do
request <- parseRequest url
runResourceT
$ runConduit$ httpSource request getSrc
.| sinkFile location
where
getSrc res = do
let success = statusIsSuccessful . getResponseStatus $ res
if success then
getResponseBody res
else
???
據我了解,如果響應成功,您希望將響應主體通過管道傳遞給某個管道,如果響應失敗,則將管道傳遞給替代管道。
我相信,最簡單的解決方案將涉及使用if ... then ... else
“選擇”管道,而您的代碼中已經有了-例如
module Main where
import Conduit ( printC
)
import Data.Conduit ( runConduitRes
, (.|)
, yield
)
import Data.Conduit.Binary ( sinkFile
)
import Network.HTTP.Simple ( parseRequest
, httpSource
, getResponseStatus
, getResponseBody
)
import Network.HTTP.Types.Status ( statusIsSuccessful
)
main :: IO ()
main = do
requestText <- init <$> readFile "notes/request.txt"
downloadURL requestText "notes/sink.txt"
downloadURL :: String -> FilePath -> IO ()
downloadURL url location = do
request <- parseRequest url
runConduitRes (httpSource request processResponse)
where
processResponse response =
if statusIsSuccessful (getResponseStatus response)
then (getResponseBody response) .| sinkFile location
else yield "an alternate operation" .| printC
您可以將yield "an alternate operation" .| printC
替換為yield "an alternate operation" .| printC
用另一個管道完成您實際需要的yield "an alternate operation" .| printC
。
注意, sinkFile location
現在僅在成功情況下執行,因此失敗情況下不會創建任何文件。
Kartin的解決方案應該可以正常工作。 您可以采取的另一種方法是使用sinkFileCautious
而不是sinkFile
,並在無效的狀態代碼上拋出運行時異常。 實際上,您可以將parseRequest
替換為parseUrlThrow
以自動獲得此行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.