You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言实现图片转Base64存储PostgreSQL时输出异常问题求助

异常原因
  1. 文件指针位置错误
    将上传的文件内容写入tempFile后,文件读写指针停留在文件末尾,后续直接读取tempFile时只能读到空字节,Base64编码中空字节对应的字符为A,因此会出现大量重复A的无效编码。
  2. JPEG转码逻辑变量作用域错误
    在image/jpeg的分支中,你声明了局部变量buf := new(bytes.Buffer),该变量仅在当前分支生效,外层用于生成Base64的全局buf完全没有被赋值为转码后的PNG内容,转码逻辑完全失效。
  3. 上传大小限制配置错误
    注释标注最大支持10MB上传,但r.ParseMultipartForm(1 << 2)实际仅配置了4字节的缓冲区,根本无法正常接收图片文件。
  4. PostgreSQL长度限制疑问解答
    PostgreSQL的text类型默认支持最大1GB的存储长度,71000字符不存在长度限制问题。但Base64编码会比原始二进制数据大33%,更推荐使用bytea类型直接存储图片二进制,或是将图片存储到本地磁盘/对象存储,数据库仅存储文件路径,性能更优。
修复方案

对应问题逐一修正,还可以优化掉不必要的临时文件读写逻辑,直接操作内存中的文件字节减少IO开销,修正后的代码如下:

import "io"

func HandleUpload(w http.ResponseWriter, r *http.Request, formFileName string) (string, string, string, error) {
    // 最大10MB上传限制,修正参数为10 << 20
    r.ParseMultipartForm(10 << 20)

    file, handler, err := r.FormFile(formFileName)
    if err != nil {
        return "", "", "", nil
    }
    defer file.Close()

    fmt.Printf("Uploaded File: %+v\n", handler.Filename)
    fmt.Printf("File Size: %+v\n", handler.Size)
    fmt.Printf("MIME Header: %+v\n", handler.Header)

    fileBytes, err := io.ReadAll(file)
    if err != nil {
        log.Println(err)
        return "", "", "", err
    }

    // 写入临时文件的逻辑保留,跳过无用的写后重读逻辑
    tempFile, err := ioutil.TempFile(TmpDirectory, "upload-*.png")
    if err != nil {
        log.Println(err)
        return "", "", "", err
    }
    defer tempFile.Close()
    if _, err := tempFile.Write(fileBytes); err != nil {
        log.Println(err)
        return "", "", "", err
    }
    fmt.Fprintf(w, "Successfully Uploaded File\n")

    contentType := http.DetectContentType(fileBytes)
    var encodeBuf []byte
    switch contentType {
    case "image/png":
        fmt.Println("Image type is already PNG.")
        encodeBuf = fileBytes
    case "image/jpeg":
        fmt.Println("Image type is JPG, converting it to PNG.")
        img, err := jpeg.Decode(bytes.NewReader(fileBytes))
        if err != nil {
            return "", "", "", errors.Wrap(err, "unable to decode jpeg")
        }
        buf := new(bytes.Buffer)
        if err := png.Encode(buf, img); err != nil {
            return "", "", "", errors.Wrap(err, "unable to encode png")
        }
        // 把转码后的内容赋值给全局编码用变量
        encodeBuf = buf.Bytes()
    default:
        return "", "", "", errors.New("unsupported image type")
    }

    imgBase64Str := base64.StdEncoding.EncodeToString(encodeBuf)
    filePath := filepath.Join(TmpDirectory, tempFile.Name())
    return handler.Filename, filePath, imgBase64Str, nil
}

内容的提问来源于stack exchange,提问作者CodingAddict

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 21:36:03