简体   繁体   English

Gin 服务 []byte 作为文件

[英]Gin serve []byte as file

I have a golang backend with gin.我有一个带有杜松子酒的 golang 后端。 Its supposed to work as a proxy for a ftp server that contains audiofiles.它应该用作包含音频文件的 ftp 服务器的代理。 So my client should be able to call the endpoint /download/filepath the Golang application is then supposed to fetch the file from a ftp server and return it as a file(no stream).所以我的客户端应该能够调用端点 /download/filepath ,然后 Golang 应用程序应该从 ftp 服务器获取文件并将其作为文件(无流)返回。

My current solution is to read the file from the ftp as []byte and temporarily write it to disk with ioutil.TempFile() and return that file with ctx.File().我当前的解决方案是从 ftp 作为 []byte 读取文件,并使用 ioutil.TempFile() 将其临时写入磁盘并使用 ctx.File() 返回该文件。

If possible I would like to skip the step where I'm creating a tempfile.如果可能的话,我想跳过创建临时文件的步骤。 Is that possible?那可能吗? Perhaps theres a way to proxy the call and directly connect the http call to the ftp call?也许有一种方法可以代理呼叫并将 http 呼叫直接连接到 ftp 呼叫?

Note I don't control the client application so I can't change it.注意我不控制客户端应用程序,所以我不能改变它。

Use Context.Data to write a []byte as the response.使用Context.Data写入[]byte作为响应。

You can also use Context.DataFromReader to copy directly from the FTP response to the HTTP response.您还可以使用Context.DataFromReader直接从 FTP 响应复制到 HTTP 响应。

HTTP responses are a stream of bytes. HTTP 响应是字节的 stream。 There's no way to get around that.没有办法解决这个问题。

You can write to the ResponseWriter as you are reading the file.您可以在读取文件时写入ResponseWriter It works just like using http.ResponseWriter .它就像使用http.ResponseWriter一样工作。

import "io"

//...

io.Copy(ctx.ResponseWriter, ftpReader)

In the gin framework to serving binary files to the client then the browser automatically downloads the file when the API is hit by the user, and the server does not need to save the file to the server (without having to save a static file), then use this method c.Data .在 gin 框架中向客户端提供二进制文件,然后浏览器会在用户点击 API 时自动下载文件,服务器不需要将文件保存到服务器(无需保存 static 文件),然后使用此方法c.Data Where the data type of the third parameter is []byte.其中第三个参数的数据类型为[]byte。 I hope this answer can be useful and easier to understand for everyone.我希望这个答案对每个人都有用并且更容易理解。 Here is a sample code.这是一个示例代码。

func DownloadFile(c *gin.Context) {
    byteFile, err := ioutil.ReadFile("./file.txt")
    if err != nil {
        fmt.Println(err)
    }

    c.Header("Content-Disposition", "attachment; filename=file-name.txt")
    c.Data(http.StatusOK, "application/octet-stream", byteFile)
}

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

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