根据 GET 请求,我的 Scotty webapp 将运行一些计算并将其结果存储在一个临时文件中,它使用file
.
现在我想在文件发送后进行一些清理(即删除临时文件) 。Scotty 似乎没有包含这样做的方法。
WAI 中是否有任何功能可以实现这一点?
根据 GET 请求,我的 Scotty webapp 将运行一些计算并将其结果存储在一个临时文件中,它使用file
.
现在我想在文件发送后进行一些清理(即删除临时文件) 。Scotty 似乎没有包含这样做的方法。
WAI 中是否有任何功能可以实现这一点?
wai 给了我们一个函数responseStream
responseStream :: Status -> ResponseHeaders -> StreamingBody -> Response
构造 a Response
out of a StreamingBody
,这实际上是一个函数
type StreamingBody = (Builder -> IO ()) -> IO () -> IO ()
给定一个“写入”动作和一个“刷新”动作,它会在某处找到一些字节并执行所有写入和刷新。
wai 还为我们提供了一个现成的responseFile
功能:
responseFile :: Status -> ResponseHeaders -> FilePath -> Maybe FilePart -> Response
但它不会在最后删除文件。我们可以通过某种方式对其进行修改吗?看来我们可以,借助responseToStream辅助函数
responseToStream :: Response -> (Status, ResponseHeaders, (StreamingBody -> IO a) -> IO a)
这“打开”了一个已经构建的Response
,允许我们调整一些东西。
像这样:
import Network.Wai
import Network.HTTP.Types.Status (status200)
import System.Directory (removeFile)
responseFileDeleting' :: FilePath -> Response
responseFileDeleting' filepath =
let (status,header,streamer) =
responseToStream $ responseFile status200 [] filepath Nothing
in responseStream status header (\write flush ->
-- this would be a good place to put a bracket, if needed
do streamer (\body -> body write flush)
removeFile filepath)
(注意:streamer
由于所有的高阶,类型有点令人费解。)
该解决方案的缺点是请求必须等到文件被删除才能完成。另一种选择可能是将文件路径发送到某种并发 队列,该队列在另一个线程中执行删除。