登录
首页 >  Golang >  Go问答

为何ParseMultipartForm方法不会造成文件句柄泄漏?

来源:stackoverflow

时间:2024-02-17 21:00:28 360浏览 收藏

编程并不是一个机械性的工作,而是需要有思考,有创新的工作,语法是固定的,但解决问题的思路则是依靠人的思维,这就需要我们坚持学习和更新自己的知识。今天golang学习网就整理分享《为何ParseMultipartForm方法不会造成文件句柄泄漏?》,文章讲解的知识点主要包括,如果你对Golang方面的知识点感兴趣,就不要错过golang学习网,在这可以对大家的知识积累有所帮助,助力开发能力的提升。

问题内容

我有一个 http 端点,它调用 net/http.(*Request).FormFile 来读取上传的文件。我注意到返回的 *multipart.File 永远不会用 Clos​​e() 关闭。这对于小文件来说很好,因为它是无操作的,但是 https://golang.org/src/net/http/request.go#L1369 r.ParseMultipartForm 似乎会将文件复制出内存并复制到如果文件大于 32MB,则为临时文件。您可以在此处看到 os.Open 调用:https://golang.org/src/mime/multipart/formdata.go?s=3614:3656#L146

AFAICT 这会泄漏文件句柄,但是当我检查进程时,我没有看到泄漏文件句柄。这是在哪里清理的?

更新:这是一个完整的测试程序:https://play.golang.org/p/79_kt46t1PQ


正确答案


multipart.form 声明了 removeall() 方法,该方法调用 os.remove(fh.tmpfile)

此方法会在 multipart.reader.readform 期间发生错误时或在请求处理后调用:

if w.req.multipartform != nil {
        w.req.multipartform.removeall()
    }

以上位于https://golang.org/src/net/http/server.go#L1957

编辑:

事实上,你可能会发现一些事情。有一个open issue提到了这一点。在问题 it is noted 中,removeall 在请求结束时被调用,但据报道文件仍然存在。

正如您还评论的那样,这可能与使用 unlink 系统调用实现的 os.remove 调用(在 unix 上)有关,其中:

如果名称是文件的最后一个链接,但仍有任何进程 打开文件,该文件将一直存在,直到 引用它的最后一个文件描述符已关闭。

总结一下,我认为您应该在 multipart.file 上自己调用 clos​​e(),如同一线程中的建议:

file, _, _ := r.FormFile("file")
defer file.Close()

这可能是一个文档错误,尽管有些人可能认为使用后关闭文件是显而易见的,但在这种特殊情况下,文档可能更明确。无论如何,此时我想您可以要求进一步澄清相关问题。

好了,本文到此结束,带大家了解了《为何ParseMultipartForm方法不会造成文件句柄泄漏?》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>