这个方法的问题在于它没有正确地将save的内容写入到writer中,并且没有将writer的内容写入到c.Writer中。

要解决这个问题,你需要将save的内容写入到writer中,并在循环结束后将writer的内容写入到c.Writer中。以下是修改后的代码:

func (srv *ImageService) ExportImage(c *gin.Context) {
	name := c.Query("name")
	id := c.Query("id")
	raw, _, err := srv.cli.ImageInspectWithRaw(context.Background(), id)
	if err != nil {
		logger.Error(err.Error())
	}
	save, err := srv.cli.ImageSave(context.Background(), raw.RepoTags)
	if err != nil {
		logger.Error(err.Error())
		msg := response.WsMsg{
			Code: 2015,
			Msg:  err.Error(),
			Name: raw.RepoTags[0],
		}
		wsResp := response.WsResp{
			Type: "docker",
			Data: msg,
		}
		marshal, err := json.Marshal(wsResp)
		if err != nil {
			logger.Error(err.Error())
			return
		}
		_, err = srv.dbus.GetWithTimeout(5*time.Second, ipc.ClientParam{
			Dest:   "com.ugreen.entry.wss",
			Path:   "/com/ugreen/entry/wss",
			Method: "SendWssDbus",
		}, string(marshal))
		if err != nil {
			logger.Error(err.Error())
			return
		}
	}
	defer func() {
		err = save.Close()
		if err != nil {
			logger.Error(err.Error())
		}
	}()
	name = fmt.Sprintf("%s.sync.tar", name)
	reader, writer := io.Pipe()
	go func() {
		defer writer.Close()
		_, err := io.Copy(writer, save)
		if err != nil {
			logger.Error(err.Error())
		}
	}()
	c.Header("Content-Disposition", "attachment; filename="+name)
	c.Header("Content-Type", "application/octet-stream")
	_, err = io.Copy(c.Writer, reader)
	if err != nil {
		logger.Error(err.Error())
		c.String(http.StatusInternalServerError, "Failed to write response stream")
		msg := response.WsMsg{
			Code: 2015,
			Msg:  err.Error(),
			Name: raw.RepoTags[0],
		}
		wsResp := response.WsResp{
			Type: "docker",
			Data: msg,
		}
		marshal, err := json.Marshal(wsResp)
		if err != nil {
			logger.Error(err.Error())
			return
		}
		_, err = srv.dbus.GetWithTimeout(5*time.Second, ipc.ClientParam{
			Dest:   "com.ugreen.entry.wss",
			Path:   "/com/ugreen/entry/wss",
			Method: "SendWssDbus",
		}, string(marshal))
		if err != nil {
			logger.Error(err.Error())
			return
		}
		return
	}
	msg := response.WsMsg{
		Code: 2014,
		Name: raw.RepoTags[0],
	}
	wsResp := response.WsResp{
		Type: "docker",
		Data: msg,
	}
	marshal, err := json.Marshal(wsResp)
	if err != nil {
		logger.Error(err.Error())
		return
	}
	_, err = srv.dbus.GetWithTimeout(5*time.Second, ipc.ClientParam{
		Dest:   "com.ugreen.entry.wss",
		Path:   "/com/ugreen/entry/wss",
		Method: "SendWssDbus",
	}, string(marshal))
	if err != nil {
		logger.Error(err.Error())
		return
	}
	c.Status(http.StatusOK)
}

这样修改后,save的内容将会被正确地写入到writer中,然后writer的内容将会被写入到c.Writer中,从而将文件流输出给前端。

unc srv ImageService ExportImagec ginContext 	name = cQueryname	id = cQueryid	raw _ err = srvcliImageInspectWithRawcontextBackground id	if err != nil 		loggerErrorerrError		save err = srvcliImageSavec

原文地址: https://www.cveoy.top/t/topic/inC4 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录