【问题标题】:Proper way of responding to a request with a temp file in Vapor使用 Vapor 中的临时文件响应请求的正确方法
【发布时间】:2021-03-02 16:15:05
【问题描述】:

我有一个正在运行的 Vapor 服务器,它正在创建文件。这些文件是临时文件,因此它们不应保留在服务器上。

目前我使用以下:

let data = try Data(contentsOf: tempURL)
try FileManager.default.removeItem(at: tempURL)
let response = Response(status: .ok, headers: HTTPHeaders(headers), body: Response.Body(data: data))

所以我读取了文件的内容,删除了该文件(因为它只是临时文件),然后回复它。

我现在看到的问题是,有时很难重现,该文件的内容只是部分提交。我还不知道到底是什么问题,但我做了一些挖掘,至少找到了一个雷达(https://openradar.appspot.com/39621032),说这个功能在 Linux 上不能正常工作(我使用它......我使用它在一个 Docker 容器中)

所以只是为了确保这不是问题,我想知道 Vapor 响应文件然后删除它的方式?!?

【问题讨论】:

    标签: swift server nsfilemanager vapor file-manager


    【解决方案1】:

    如果这个问题仍然存在,我想提出我的解决方案。我的系统是 Vapor 4.49.0、Swift 5.5、macOS 11.6(应该可以在 Ubuntu 20.04 上运行)。 我将在这里发布小而完整的文件routes.swift,请看:

    //
    //  routes.swift
    //
    //
    //  Created by Alex on 09.10.2021.
    //
    
    import Vapor
    
    func routes(_ app: Application) throws {
        
        app.get(":fileName") { req -> EventLoopFuture<Response> in
            let badResponse = Response(status: .forbidden, version: .http1_0, headers: HTTPHeaders(), body: .empty)
            
            guard let fileName = req.parameters.get("fileName") else {
                return req.eventLoop.future(badResponse)
            }
            
            let filePath = app.directory.workingDirectory + fileName
            
            guard let file = File(filePath: filePath) else {
                return req.eventLoop.future(badResponse)
            }
            
            return req.fileio.collectFile(at: filePath).map { biteBuffer in
                let body = Response.Body(buffer: biteBuffer)
                
                let response = Response(status: .ok, headers: HTTPHeaders(), body: body)
                
                file.delete()
                
                return response
            }
        }
        
    }
    
    final class File {
        
        private let fileManager = FileManager.default
        private let url: URL
        
        init?(filePath: String) {
            guard let url = URL(string: "file:" + filePath) else {
                return nil
            }
            
            self.url = url
        }
        
        func delete() {
            do {
                try fileManager.removeItem(at: url)
            } catch {
            }
        }
        
    }
    

    我想听听你的回复。如果你能测试这段代码,我会很高兴。谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-29
      • 1970-01-01
      • 2018-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多