简体   繁体   English

损坏的 zip 文件在 golang 中发送 REST API

[英]Corrupted zip file is sent in golang REST API

I've searched a lot about this issue, but I couldn't find a suitable solution.我已经搜索了很多有关此问题的信息,但找不到合适的解决方案。 I want to find some records from a mongodb collection and save each record to a json file, then zip them and send back as the response of an REST API.我想从 mongodb 集合中找到一些记录,并将每条记录保存到 json 文件,然后将它们保存到 zip,并作为 REST API 的响应发回。

    // each record should be saved in a file
    var records []iodefRepo.IodefRecord
    if cur, err := h.iodefRepo.IodefCollection().Find(helper.Context(), filter, options.Find().SetSort(M{"received_at": -1})); err != nil {
        return helper.WrapInternalErr("while finding iodef, err=" + err.Error())
    } else if err := cur.All(helper.Context(), &records); err != nil {
        return helper.WrapInternalErr("while un-cursoring records, err=" + err.Error())
    }

    -------------------------------------------------------
    resultFile, err := os.Create(fmt.Sprint(fileName, ".zip"))
    if err != nil {
        return helper.WrapInternalErr("while creating the result file, err=" + err.Error())
    }

    writer := zip.NewWriter(resultFile)
    // files is a [][]byte that each element is []byte of json.Unmarshal
    for i, f := range files {
        if file, err := writer.Create(fmt.Sprint("IncidentName=", records[i].Document.Incidents[0].IncidentID.Name, ", IncidentData=", records[i].Document.Incidents[0].IncidentID.Data, ".", format)); err != nil {
            return helper.WrapInternalErr("while creating iodef file, err=" + err.Error())
        } else if _, err := file.Write(f); err != nil {
            return helper.WrapInternalErr("while writing to iodef file, err=" + err.Error())
        }
    }

    helper.AddResponseHeader("Content-Type", "application/zip")
    helper.AddResponseHeader("Content-Transfer-Encoding", "binary")
    helper.AddResponseHeader("Content-Disposition", "attachment; filename=export.zip")

    _ = writer.Close()
    _ = resultFile.Close()

    if result, err := os.ReadFile(fileName + ".zip"); err != nil {
        return helper.WrapInternalErr("while reading zip file, err=" + err.Error())
    } else {
        // this result which is a []byte will be write to standard ResponseWriter
        // the same as err := w.Write(result); mention that I have ckecked and there
        // is no error in any of the steps and everything is done without any errors.
        return helper.WrapOk(result)
    }
    

I save the zip file after generation on server and test it, it works completely fine but when I read the response in postman and save it as a zip, The file is corrupted, I don't know why and I don't have any clue to solve the issue, There are similar issues but none of them worked.我在服务器上生成生成后保存 zip 文件并对其进行测试,它完全可以正常工作但是当我读取 postman 中的响应并将其另存为 zip 时,文件已损坏,我不知道为什么而且我没有任何解决问题的线索,有类似的问题,但没有一个有效。 Response of the API in postman is exactly the same size as file that has been generated on serverside. postman 中 API 的响应与服务器端生成的文件大小完全相同。

I did try a few stuffs such as using different headers and different methods to read the result zip file, none of them worked, I think os.ReadFile is the best option to read a binary file completely.我确实尝试了一些东西,例如使用不同的标头和不同的方法来读取结果 zip 文件,但都没有用,我认为 os.ReadFile 是完全读取二进制文件的最佳选择。 I do not have any clue of why this issue exists.我不知道为什么存在这个问题。 Just want to emphasize, the generated zip file is working properly on serverside, after sending it as a binary array using os.ReadFile and standard http.ResponseWriter.Write, file won't work properly.只是想强调一下,生成的 zip 文件在服务器端正常工作,在使用 os.ReadFile 和标准 http.ResponseWriter.Write 将其作为二进制数组发送后,文件将无法正常工作。

Finally I found the answer, I still do not know what is wrong with my previous solution, but when I use http.ServeFile(w, r, "/path/to/zip_file") function instead of using ResponseWriter.Write(fileBytes) , the problem solved.最后我找到了答案,我仍然不知道我以前的解决方案有什么问题,但是当我使用http.ServeFile(w, r, "/path/to/zip_file") function 而不是使用ResponseWriter.Write(fileBytes) ,问题解决了。 It is actually so strange that using ResponseWriter.Write(fileBytes) could cause the issue.使用ResponseWriter.Write(fileBytes)可能会导致问题,这实际上很奇怪。 If anyone have any idea of why that happens, let me know about it.如果有人知道为什么会这样,请告诉我。 Thanks.谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM