首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >下载戈朗api图像中损坏的图像文件

下载戈朗api图像中损坏的图像文件
EN

Stack Overflow用户
提问于 2020-02-04 09:50:05
回答 1查看 1.1K关注 0票数 2

我正在用golang构建一个简单的测试API,用于上传和下载图像文件(PNG、JPEG、JPG):

/pic发布上传图像并将其保存到文件夹;/pic GET用于将图像下载到客户端。

我已经成功地构建了/pic帖子,并成功地将图像上传到服务器的文件中。我可以打开存储文件夹中的文件。(在windows localhost服务器和ubuntu服务器中)

但是,当我构建用于下载图片的/pic GET时,我可以将该文件下载到客户端(我的计算机),但是下载的文件以某种方式损坏了,因为当我尝试用不同的图像查看器(如图片库或Photoshop )打开它时,它说“看起来我们不支持这种文件格式”。因此,下载似乎并不成功。

邮递员结果:

图库中的文件打开:

对于为什么会发生这种情况,我应该如何解决它,有什么想法吗?

下载图片的golang代码如下(省略错误处理):

代码语言:javascript
复制
func PicDownload(w http.ResponseWriter, r *http.Request){

   request := make(map[string]string)
   reqBody, _ := ioutil.ReadAll(r.Body)
   err = json.Unmarshal(reqBody, &request)
   // Error handling

   file, err := os.OpenFile("./resources/pic/" + request["filename"], os.O_RDONLY, 0666)
   // Error handling

   buffer := make([]byte, 512)
   _, err = file.Read(buffer)
   // Error handling

   contentType := http.DetectContentType(buffer)

   fileStat, _ := file.Stat()

   // Set header
   w.Header().Set("Content-Disposition", "attachment; filename=" + request["filename"])
   w.Header().Set("Content-Type", contentType)
   w.Header().Set("Content-Length", strconv.FormatInt(fileStat.Size(), 10))

   // Copying the file content to response body
   io.Copy(w, file)

   return
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-04 11:26:01

当您从文件中读取前512字节以确定内容类型时,基础文件流指针向前移动512字节。稍后调用io.Copy时,从该位置继续读取。

有两种方法可以纠正这种情况。

首先是在调用file.Seek(0, io.SeekStart)之前调用io.Copy()。这将使指针返回到文件的开始。此解决方案需要最少的代码,但意味着从文件中读取相同的512字节两次,这会造成一些开销。

第二个解决方案是使用buffer := make([]byte, fileStat.Size()创建一个包含整个文件的缓冲区,并为http.DetectContentType()调用使用该缓冲区,并编写输出(使用w.Write(buffer)而不是使用io.Copy() )。这种方法可能会同时将整个文件加载到内存中,这对于非常大的文件来说并不理想(io.Copy使用32 at块而不是加载整个文件)。

注意:正如Peter在评论中提到的,您必须确保用户不能以文件名的形式发布../../或其他内容来遍历您的文件系统。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60054675

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档