go 使用form表单 分片上传 阿里云 oss
// 阿里云oss分片上传图片
func MuUploadFile(file *multipart.FileHeader)(string,error) {
client, err := oss.New("aliyunoss.endpoint, "aliyunoss.access-key-id", "aliyunoss.access-key-secret")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 填写Bucket名称。
bucketName := "revibook-images"
// 填写Object完整路径。Object完整路径中不能包含Bucket名称。
option := oss.ContentType("image/jpg")
uploadsPath := "images"
fileSuffix := path.Ext(file.Filename)
//fmt.Printf("文件后缀名:%s",fileSuffix)
fileName := upload.StrToMd5(file.Filename) + fileSuffix
//上传阿里云路径 文件名格式 自己可以改 建议保证唯一性
objectName := filepath.Join(uploadsPath, time.Now().Format("2006-01-02")) + "/" + fileName
// 读取本地文件。
fd, openError := file.Open()
if openError != nil {
global.LOG.Error("function file.Open() Failed", zap.Any("err", openError.Error()))
return "", errors.New("function file.Open() Failed, err:" + openError.Error())
}
// 获取存储空间。
bucket, err := client.Bucket(bucketName)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 将本地文件分片,且分片数量指定为3。
chunks, err := SplitFileByPartNum(file.Size, 3)
// 设置存储类型为标准存储。
storageType := oss.ObjectStorageClass(oss.StorageStandard)
// 步骤1:初始化一个分片上传事件,并指定存储类型为标准存储。
imur, err := bucket.InitiateMultipartUpload(objectName, storageType, option)
// 步骤2:上传分片。
var parts []oss.UploadPart
for _, chunk := range chunks {
fd.Seek(chunk.Offset, os.SEEK_SET)
// 调用UploadPart方法上传每个分片。
part, err := bucket.UploadPart(imur, fd, chunk.Size, chunk.Number)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
parts = append(parts, part)
}
// 步骤3:完成分片上传,指定文件可以预览。
_, err = bucket.CompleteMultipartUpload(imur, parts, option)
if err != nil {
fmt.Println("Error:", err)
return "",err
}
//返回预览路径
return config.MustString("aliyunoss.bucket-url")+"/"+objectName,nil
}
// 分片计算
func SplitFileByPartNum(size int64, chunkNum int) ([]oss.FileChunk, error) {
if chunkNum <= 0 || chunkNum > 10000 {
return nil, errors.New("chunkNum invalid")
}
if int64(chunkNum) > size {
return nil, errors.New("oss: chunkNum invalid")
}
var chunks []oss.FileChunk
var chunk = oss.FileChunk{}
var chunkN = (int64)(chunkNum)
for i := int64(0); i < chunkN; i++ {
chunk.Number = int(i + 1)
chunk.Offset = i * (size / chunkN)
if i == chunkN-1 {
chunk.Size = size/chunkN + size%chunkN
} else {
chunk.Size = size / chunkN
}
chunks = append(chunks, chunk)
}
return chunks, nil
}