golang 接受前端上传文件,将文件写入本地,校验 而后上传OSS

管理后台操作流程:

  1. 前端上传 zip / 单个文件
  2. 后端接收到后,将文件写入 /tmp 目录
  3. 调用一些 api 对 /tmp 目录下的文件 进行 文件大小、尺寸 校验
  4. 文件满足要求,将文件上传oss
  5. 返给前端oss url

主要难点:

  1. 读取内存文件,写入本地
  2. 素材校验
  3. 上传失败重试

参考代码:

代码段1

func writeLocal(file multipart.File, fileName string) (string, string, string, error) {
	id := idgen.GenId()
	day := time.Now().Format("2006-01-02")
	path := conf.C.App.FileSrcDir + "/" + day + "/" + id + "/" + fileName

	var fd *os.File
	var err error

	dir := filepath.Dir(path)
	err = os.MkdirAll(dir, os.ModePerm)
	if err != nil {
		return "", "", "", err
	}

	fd, err = os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		return "", "", "", err
	}
	defer fd.Close()

	wt := bufio.NewWriter(fd)
	file.Seek(0, os.SEEK_SET)
	_, err = io.Copy(wt, file)
	if err != nil {
		return "", "", "", err
	}
	wt.Flush()

	return path, day, id, err
}

 代码段2:

func DecodeImage(path string) (int, int, error) {
	var err error
	reader, err := os.Open(path)
	if err != nil {
		return 0, 0, err
	}
	defer reader.Close()
	im, _, err := image.DecodeConfig(reader)
	if err != nil {
		return 0, 0, err
	}
	logger.Infof("图片分辨率 %v %v %v", path, im.Width, im.Height)
	return im.Width, im.Height, nil
}


// 文件大小 

fe, _ := os.Stat(path)

代码段3:

// 解压缩zip包,放到新目录
func Unzip(src string, dest string) ([]string, error) {

	var filenames []string

	r, err := zip.OpenReader(src)
	if err != nil {
		return filenames, err
	}
	defer r.Close()

	for _, f := range r.File {
		fpath := filepath.Join(dest, f.Name)

		// Check for ZipSlip. More Info: http://bit.ly/2MsjAWE
		if !strings.HasPrefix(fpath, filepath.Clean(dest)+string(os.PathSeparator)) {
			return filenames, fmt.Errorf("%s: illegal file path", fpath)
		}

		filenames = append(filenames, fpath)

		if f.FileInfo().IsDir() {
			// Make Folder
			os.MkdirAll(fpath, os.ModePerm)
			continue
		}

		// Make File
		if err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil {
			return filenames, err
		}

		outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
		if err != nil {
			return filenames, err
		}

		rc, err := f.Open()
		if err != nil {
			return filenames, err
		}

		_, err = io.Copy(outFile, rc)

		// Close the file without defer to close before next iteration of loop
		outFile.Close()
		rc.Close()

		if err != nil {
			return filenames, err
		}
	}
	return filenames, nil
}

代码段4:

	for i := 0; i < 3; i++ {
		err := bucket.PutObjectFromFile(key, path)
		if err == nil {
			break
		}
		if i == 2 {
			logger.Errorf("上传出错 %v %v", err, key)
			return "", err
		}
		time.Sleep(time.Duration(2) * time.Second)
	}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Golang中,可以通过使用`net/http`包来读取前端传输的文件内容。 首先,服务端需要设置一个HTTP路由处理函数来接收前端传输的文件。这可以通过使用`http.HandleFunc()`函数来实现。在路由处理函数中,可以使用`request.ParseMultipartForm()`函数来解析前端发送的multipart/form-data类型的表单数据。 示例代码如下所示: ```go package main import ( "net/http" "fmt" ) func fileHandler(w http.ResponseWriter, r *http.Request) { err := r.ParseMultipartForm(32 << 20) // 设置最大文件大小为32MB if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } file, _, err := r.FormFile("file") // 获取文件内容 if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer file.Close() // 处理文件内容,例如保存至本地或上传至云端 // ... fmt.Fprint(w, "文件上传成功") } func main() { http.HandleFunc("/upload", fileHandler) http.ListenAndServe(":8080", nil) } ``` 在上述代码中,`fileHandler`函数用于处理前端传输的文件数据。通过调用`r.FormFile("file")`可以获取到文件的内容。接下来,你可以根据具体的需求对文件内容进行处理,例如保存至本地或上传至云端。 最后,通过调用`http.HandleFunc()`函数设置服务器的路由处理函数,并使用`http.ListenAndServe()`函数监听指定的端口,等待客户端的请求。 这样,当前端向服务端发送文件内容时,服务端可以通过上述代码读取并处理文件内容。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值