全部产品
Search
文档中心

对象存储 OSS:Go简单上传

更新时间:Sep 30, 2024

本文介绍如何通过简单上传方法将本地文件快速上传到OSS,这种方式简单直观,适用于快速将本地文件上传到云端存储。

注意事项

  • 本文以华东1(杭州)外网Endpoint为例。如果您希望通过与OSS同地域的其他阿里云产品访问OSS,请使用内网Endpoint。关于OSS支持的Region与Endpoint的对应关系,请参见OSS访问域名、数据中心、开放端口

  • 本文以从环境变量读取访问凭证为例。如何配置访问凭证,请参见配置访问凭证

  • 本文以OSS域名新建OSSClient为例。如果您希望通过自定义域名、STS等方式新建OSSClient,请参见初始化

  • 要简单上传,您必须有oss:PutObject权限。具体操作,请参见为RAM用户授权自定义的权限策略

示例代码

以下代码用于将本地文件上传到目标存储空间examplebucket中exampledir目录下的exampleobject.txt文件:

package main

import (
	"log"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Failed to create credentials provider: %v", err)
	}

	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	endpoint := "https://oss-cn-hangzhou.aliyuncs.com" // 请替换为实际的Endpoint
	client, err := oss.New(endpoint, "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		log.Fatalf("Failed to create OSS client: %v", err)
	}

	// 填写存储空间名称,例如examplebucket。
	bucketName := "examplebucket" // 请替换为实际的Bucket名称
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		log.Fatalf("Failed to get bucket: %v", err)
	}

	// 依次填写Object的完整路径(例如exampledir/exampleobject.txt)和本地文件的完整路径(例如D:\\localpath\\examplefile.txt)。
	objectKey := "exampledir/exampleobject.txt"                              // 请替换为实际的对象Key
	localFilePath := "D:\\localpath\\examplefile.txt" // 请替换为实际的本地文件路径
	err = bucket.PutObjectFromFile(objectKey, localFilePath)
	if err != nil {
		log.Fatalf("Failed to put object from file: %v", err)
	}

	log.Println("File uploaded successfully.")
}

常见使用场景

如何上传字符串?

您可以使用以下代码将字符串上传至目标存储空间examplebucket中exampledir目录下的exampleobject.txt文件。

package main

import (
	"log"
	"strings"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Failed to create credentials provider: %v", err)
	}

	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	endpoint := "https://oss-cn-hangzhou.aliyuncs.com" // 请替换为实际的Endpoint
	client, err := oss.New(endpoint, "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		log.Fatalf("Failed to create OSS client: %v", err)
	}

	// 填写存储空间名称,例如examplebucket。
	bucketName := "examplebucket" // 请替换为实际的Bucket名称
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		log.Fatalf("Failed to get bucket: %v", err)
	}

	objectKey := "exampledir/exampleobject.txt" // 请替换为实际的对象Key
	content := "Hello OSS"
	err = bucket.PutObject(objectKey, strings.NewReader(content))
	if err != nil {
		log.Fatalf("Failed to put object: %v", err)
	}

	log.Println("File uploaded successfully.")
}

如何上传Byte数组?

您可以使用以下代码将Byte数组上传至目标存储空间中exampledir目录下的exampleobject.txt文件:

package main

import (
	"bytes"
	"log"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Failed to create credentials provider: %v", err)
	}

	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	endpoint := "https://oss-cn-hangzhou.aliyuncs.com" // 请替换为实际的Endpoint
	client, err := oss.New(endpoint, "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		log.Fatalf("Failed to create OSS client: %v", err)
	}

	// 填写存储空间名称,例如examplebucket。
	bucketName := "examplebucket" // 请替换为实际的Bucket名称
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		log.Fatalf("Failed to get bucket: %v", err)
	}

	err = bucket.PutObject("exampledir/exampleobject.txt", bytes.NewReader([]byte("yourObjectValueByteArrary")))
	if err != nil {
		log.Fatalf("Failed to put object: %v", err)
	}

	log.Println("File uploaded successfully.")
}

如何上传文件流?

您可以使用以下代码将文件流上传至目标存储空间中exampledir目录下的exampleobject.txt文件:

package main

import (
	"log"
	"os"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Failed to create credentials provider: %v", err)
	}

	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	endpoint := "https://oss-cn-hangzhou.aliyuncs.com" // 请替换为实际的Endpoint
	client, err := oss.New(endpoint, "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		log.Fatalf("Failed to create OSS client: %v", err)
	}

	// 填写存储空间名称,例如examplebucket。
	bucketName := "examplebucket" // 请替换为实际的Bucket名称
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		log.Fatalf("Failed to get bucket: %v", err)
	}

	// 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
	localFilePath := "D:\\localpath\\examplefile.txt" // 请替换为实际的本地文件路径
	file, err := os.Open(localFilePath)
	if err != nil {
		log.Fatalf("Failed to open file: %v", err)
	}
	defer file.Close()

	// 将文件流上传至exampledir目录下的exampleobject.txt文件。
	objectKey := "exampledir/exampleobject.txt" // 请替换为实际的对象Key
	err = bucket.PutObject(objectKey, file)
	if err != nil {
		log.Fatalf("Failed to put object: %v", err)
	}

	log.Println("File uploaded successfully.")
}

如何上传网络流?

您可以使用以下代码将网络流上传至目标存储空间中exampledir目录下的exampleobject.txt文件:

package main

import (
	"io"
	"log"
	"net/http"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Failed to create credentials provider: %v", err)
	}

	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	endpoint := "https://oss-cn-hangzhou.aliyuncs.com" // 请替换为实际的Endpoint
	client, err := oss.New(endpoint, "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		log.Fatalf("Failed to create OSS client: %v", err)
	}

	// 填写存储空间名称,例如examplebucket。
	bucketName := "examplebucket" // 请替换为实际的Bucket名称
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		log.Fatalf("Failed to get bucket: %v", err)
	}

	// 填写Object的完整路径,例如exampledir/exampleobject.txt。
	objectName := "exampledir/exampleobject.txt"

	// 指定待上传的网络流。
	resp, err := http.Get("https://www.aliyun.com/")
	if err != nil {
		log.Fatalf("Failed to fetch URL: %v", err)
	}
	defer resp.Body.Close()

	// 将网络流上传至OSS。
	err = bucket.PutObject(objectName, io.Reader(resp.Body))
	if err != nil {
		log.Fatalf("Failed to put object: %v", err)
	}

	log.Println("File uploaded successfully.")
}

如何创建目录?

与传统的文件系统不同,OSS内部采用扁平结构存储数据。所有数据都以对象(Object)的形式保存在存储空间(Bucket)中。为了方便管理,OSS控制台将所有以正斜线(/)结尾的对象显示为目录,从而实现类似于目录的功能。通过这种层次结构,您可以组织文件,实现分组并简化权限管理。

您可以使用以下代码创建目录:

package main

import (
	"bytes"
	"log"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Failed to create credentials provider: %v", err)
	}

	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	endpoint := "yourEndpoint"
	client, err := oss.New(endpoint, "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		log.Fatalf("Failed to create OSS client: %v", err)
	}

	// 填写存储空间名称,例如examplebucket。
	bucketName := "examplebucket"
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		log.Fatalf("Failed to get bucket '%s': %v", bucketName, err)
	}

	// 填写目录名称,目录需以正斜线结尾。
	dirName := "exampledir/"
	err = bucket.PutObject(dirName, bytes.NewReader([]byte("")))
	if err != nil {
		log.Fatalf("Failed to create directory '%s': %v", dirName, err)
	}

	log.Printf("Directory '%s' created successfully", dirName)
}

当使用完目录后,您可以使用以下代码删除目录及目录下的所有文件:

package main

import (
	"log"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Failed to create credentials provider: %v", err)
	}

	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	endpoint := "yourEndpoint"
	client, err := oss.New(endpoint, "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		log.Fatalf("Failed to create OSS client: %v", err)
	}

	// 填写Bucket名称。
	bucketName := "examplebucket"
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		log.Fatalf("Failed to get bucket '%s': %v", bucketName, err)
	}

	// 填写待删除目录的完整路径,完整路径中不包含Bucket名称。
	prefix := oss.Prefix("log/")
	marker := oss.Marker("")
	count := 0

	for {
		// 列出指定前缀下的所有对象。
		lor, err := bucket.ListObjects(marker, prefix)
		if err != nil {
			log.Fatalf("Failed to list objects in bucket '%s' with prefix '%s': %v", bucketName, prefix, err)
		}

		objects := []string{}
		for _, object := range lor.Objects {
			objects = append(objects, object.Key)
		}

		if len(objects) == 0 {
			break
		}

		// 删除目录及目录下的所有文件。
		// 将oss.DeleteObjectsQuiet设置为true,表示不返回删除结果。
		delRes, err := bucket.DeleteObjects(objects, oss.DeleteObjectsQuiet(true))
		if err != nil {
			log.Fatalf("Failed to delete objects in bucket '%s': %v", bucketName, err)
		}

		if len(delRes.DeletedObjects) > 0 {
			log.Fatalf("Some objects failed to delete: %v", delRes.DeletedObjects)
		}

		count += len(objects)

		// 更新分页参数。
		marker = oss.Marker(lor.NextMarker)
		if !lor.IsTruncated {
			break
		}
	}

	log.Printf("Success, total delete object count: %d", count)
}

如何使用进度条?

您可以使用进度条查看上传文件的进度。下面的代码以Bucket.PutObjectFromFile方法为例,介绍如何使用进度条。

package main

import (
	"log"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

// 定义进度条监听器。
type OssProgressListener struct{}

// 定义进度变更事件处理函数。
func (listener *OssProgressListener) ProgressChanged(event *oss.ProgressEvent) {
	switch event.EventType {
	case oss.TransferStartedEvent:
		log.Printf("Transfer Started, ConsumedBytes: %d, TotalBytes: %d.\n", event.ConsumedBytes, event.TotalBytes)
	case oss.TransferDataEvent:
		log.Printf("\rTransfer Data, ConsumedBytes: %d, TotalBytes: %d, %d%%.", event.ConsumedBytes, event.TotalBytes, event.ConsumedBytes*100/event.TotalBytes)
	case oss.TransferCompletedEvent:
		log.Printf("\nTransfer Completed, ConsumedBytes: %d, TotalBytes: %d.\n", event.ConsumedBytes, event.TotalBytes)
	case oss.TransferFailedEvent:
		log.Printf("\nTransfer Failed, ConsumedBytes: %d, TotalBytes: %d.\n", event.ConsumedBytes, event.TotalBytes)
	default:
		log.Printf("Unknown Event Type: %d\n", event.EventType)
	}
}

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Error: %v", err)
	}

	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	endpoint := "yourEndpoint" // 替换为实际的Endpoint
	client, err := oss.New(endpoint, "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		log.Fatalf("Error: %v", err)
	}

	// 填写存储空间名称。
	bucketName := "yourBucketName"
	// 填写不包含Bucket名称在内的Object的完整路径。
	objectName := "yourObjectName"
	// 填写本地文件的完整路径。
	localFile := "yourLocalFile"

	bucket, err := client.Bucket(bucketName)
	if err != nil {
		log.Fatalf("Error: %v", err)
	}

	// 带进度条的上传。
	err = bucket.PutObjectFromFile(objectName, localFile, oss.Progress(&OssProgressListener{}))
	if err != nil {
		log.Fatalf("Error: %v", err)
	}

	log.Println("Upload completed successfully!")
}

相关文档

  • 关于简单上传的完整示例代码,请参见GitHub示例

  • 关于简单上传的API接口说明,请参见PutObject