【问题标题】:Handle Http Upload Zip file in Golang在 Golang 中处理 Http Upload Zip 文件
【发布时间】:2024-04-14 18:30:02
【问题描述】:

我正在使用 golang net/http 包通过邮递员检索上传的 zip 文件。 附件link。它不是危险文件。欢迎随时查看。

开发环境

  • 本地机器 m1 macbook pro golang 1.17.2 - 没问题
  • 服务器 docker 映像 golang:1.17.5-stretch - 出现问题。

用于捕获 post 表单 transSourceFile 文件的代码。

func HandleFileReqTest(w http.ResponseWriter, req *http.Request, params map[string]string) err {

    if err := req.ParseMultipartForm(32 << 20); err != nil {
       return err
    }

    file, header, err := req.FormFile("transSourceFile")
    if err != nil {
       return err
    }
    defer file.Close()
    fmt.Println("header.Size:", header.Size)
    return nil
}

我试过下面的代码也没用

func HandleFileReqTest(w http.ResponseWriter, req *http.Request, params map[string]string) err {
    if err := req.ParseForm(); err != nil {
        return err
    }
    req.ParseMultipartForm(32 << 20)
    file, header, err := req.FormFile("transSourceFile")
    if err != nil {
        return err
    }
    defer file.Close()
    fmt.Println("header.Size:", header.Size)
    return nil
}

结果: 本地机器的文件大小与原始文件相同。 使用 golang:1.17.5-stretch 的服务器与原始文件相比,文件大小不同。

因此,我无法在服务器中解压缩文件。有人可以帮忙吗?

【问题讨论】:

  • 问题中没有任何内容特定于 docker 或者它是 ZIP 文件 - 它只是关于上传文件而不接收在服务器上上传的内容。我已经删除了这些误导性标签并更改了标题。
  • “与原始文件相比,带有 golang:1.17.5-stretch 的服务器得到了不同的文件大小。” - 究竟什么是不同的大小:比原始文件多或少?如果更少:传输的字节是否匹配,即它只是缺少结尾?如果更多:原始字节是否匹配,即最后是否只有垃圾?或者这里到底有什么不同?也可能上传本身已损坏,并且在不同的 golang 版本中对损坏的解释不同?请准确提供上传的样子(如数据包捕获)。
  • @SteffenUllrich 感谢您删除误导性标签,如果我这样做了。添加它是因为它可能是开发问题。
  • @SteffenUllrich 服务器中的文件大小大于原始文件大小。顺便提一句。到目前为止,主要问题不是无法解压缩文件。主要问题在于 zip 文件头。 req.FormFile("transSourceFile") 中的大小值显示与原始相比更多的字节。 Origin 有 171 个字节,header.Size 值为 205。你能建议我如何比较这两个文件吗?
  • @SteffenUllrich 我用 zip 撤消了标题。到目前为止,它只发生在服务器处理 zip 文件中。我曾尝试过服务器处理非 zip 文件。非 zip 文件正在工作。我在本地 zip 文件上没有问题。

标签: go server upload zip


【解决方案1】:

您需要将表单文件复制到实际文件中:

f, err := os.Create("some.zip")
defer f.Close()
n, err := io.Copy(f, file)

【讨论】:

  • 这取决于上传的大小。文件可以在内存中:cs.opensource.google/go/go/+/refs/tags/go1.17.6:src/mime/…
  • 感谢您的想法。我确实将表单文件复制到实际文件,但这是我获得文件值后的过程。到目前为止,我面临的是来自 req.FormFile("transSourceFile") 的 header.Size 值不同。目前的情况是在我的本地机器上,我得到的 header.Size 值为 171,与原始文件相同。在服务器中,我得到的 header.Size 值为 205,这与原始文件不同。据我所知,这是在 zip 文件中发生的。其他文件类型还不知道。
【解决方案2】:

数据未完全刷新到文件中。您应该先关闭文件以确保数据已完全刷新。

  // create a local file filename
    dst, err := os.Create("filename.zip")

      // save it
     fl, err = io.Copy(dst, src)

     // Close the file
     dst.Close()

     stat, _ := dst.Stat()

 //Now check the size stat.Size() or header.Size after flushing the file.

【讨论】:

  • 与新建文件无关。问题是我从 req.FormFile("transSourceFile") 得到了错误的数据信息。如果得到错误的数据,它也会保存错误的数据。此问题仅发生在服务器 zip 文件上。我在本地 zip 文件上没有问题