This topic describes how to upload objects to a versioning-enabled bucket.
Usage notes
In this topic, the public endpoint of the China (Hangzhou) region is used. If you want to access OSS from other Alibaba Cloud services in the same region as OSS, use an internal endpoint. For more information about OSS regions and endpoints, see Regions and endpoints.
In this topic, access credentials are obtained from environment variables. For more information about how to configure access credentials, see Configure access credentials.
In this topic, an OSSClient instance is created by using an OSS endpoint. If you want to create an OSSClient instance by using custom domain names or Security Token Service (STS), see Initialization.
To upload an object, you must have the
oss:PutObject
permission. For more information, see Attach a custom policy to a RAM user.
Sample code
Simple upload
If you upload an object to a versioning-enabled bucket, OSS generates a unique version ID for the object and includes the version ID in the x-oss-version-id response header. If you upload an object to a versioning-suspended bucket, the version ID generated for the object is null. If you upload an object with the same name as an existing object to a versioning-suspended bucket, the existing object is overwritten. This way, each object has only a single version whose version ID is null.
The following sample code provides an example on how to upload an object to a versioning-enabled bucket by using simple upload:
package main
import (
"log"
"net/http"
"strings"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Failed to create credentials provider: %v", err)
}
// Create an OSSClient instance.
// Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify your actual endpoint.
endpoint := "yourEndpoint"
client, err := oss.New(endpoint, "", "", oss.SetCredentialsProvider(&provider))
if err != nil {
log.Fatalf("Failed to create OSS client: %v", err)
}
// Specify the name of the bucket.
bucketName := "yourBucketName"
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Fatalf("Failed to get bucket '%s': %v", bucketName, err)
}
var retHeader http.Header
// Upload the string. Use oss.GetResponseHeader to retrieve the returned header.
// Specify the full path of the object. Do not include the bucket name in the full path.
objectName := "yourObjectName"
objectValue := "yourObjectValue"
err = bucket.PutObject(objectName, strings.NewReader(objectValue), oss.GetResponseHeader(&retHeader))
if err != nil {
log.Fatalf("Failed to put object '%s': %v", objectName, err)
}
// Display the value of the x-oss-version-id header.
versionId := oss.GetVersionId(retHeader)
log.Printf("x-oss-version-id: %s", versionId)
}
Append upload
In a versioning-enabled bucket, the AppendObject operation can be performed only on an object whose current version is an appendable object.
When you perform the AppendObject operation on the current version of an appendable object, OSS does not generate a previous version for the object.
When you perform the PutObject or DeleteObject operation on the current version of an appendable object, OSS saves the appendable object as a previous version that cannot be appended any more.
The AppendObject operation cannot be performed on the current version of a non-appendable object such as a normal object or a delete marker.
The following sample code provides an example on how to upload an object to a versioning-enabled bucket by using append upload:
package main
import (
"log"
"net/http"
"strings"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Failed to create credentials provider: %v", err)
}
// Create an OSSClient instance.
// Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify your actual endpoint.
endpoint := "yourEndpoint"
client, err := oss.New(endpoint, "", "", oss.SetCredentialsProvider(&provider))
if err != nil {
log.Fatalf("Failed to create OSS client: %v", err)
}
// Specify the name of the bucket.
bucketName := "yourBucketName"
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Fatalf("Failed to get bucket '%s': %v", bucketName, err)
}
// The position for the first append upload is 0, and the position for the next append upload is included in the response. The position from which the next append operation starts is the current length of the object.
// Specify the full path of the object. Do not include the bucket name in the full path.
objectName := "yourObjectName"
var retHeader http.Header
var nextPos int64 = 0
// Perform the first append operation.
nextPos, err = bucket.AppendObject(objectName, strings.NewReader("YourObjectAppendValue1"), nextPos, oss.GetResponseHeader(&retHeader))
if err != nil {
log.Fatalf("Failed to append object '%s': %v", objectName, err)
}
log.Printf("x-oss-version-id: %s", retHeader.Get("x-oss-version-id"))
// Perform the second append operation.
nextPos, err = bucket.AppendObject(objectName, strings.NewReader("YourObjectAppendValue2"), nextPos, oss.GetResponseHeader(&retHeader))
if err != nil {
log.Fatalf("Failed to append object '%s': %v", objectName, err)
}
log.Printf("x-oss-version-id: %s", oss.GetVersionId(retHeader))
// You can append content to an object multiple times.
}
Multipart upload
If you call the CompleteMultipartUpload operation to complete the multipart upload task for an object in a versioning-enabled bucket, OSS generates a unique version ID for the object and returns the version ID as the value of the x-oss-version-id header in the response.
The following sample code provides an example on how to upload an object to a versioning-enabled bucket by using multipart upload:
package main
import (
"fmt"
"os"
"net/http"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// Create an OSSClient instance.
// Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify your actual endpoint.
client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// Specify the name of the bucket.
bucketName := "examplebucket"
// Specify the full path of the object. Do not include the bucket name in the full path.
objectName := "exampleobject.txt"
// Specify the full path of the local file that you want to upload. By default, if you do not specify the full path of a local file, the local file is uploaded from the path of the project to which the sample program belongs.
locaFilename := "D:\\localpath\\examplefile.txt"
// Use oss.GetResponseHeader to obtain the returned header.
var retHeader http.Header
bucket, err := client.Bucket(bucketName)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
chunks, err := oss.SplitFileByPartNum(locaFilename, 3)
fd, err := os.Open(locaFilename)
defer fd.Close()
// Step 1: Initiate a multipart upload task.
imur, err := bucket.InitiateMultipartUpload(objectName)
// Step 2: Upload the parts.
var parts []oss.UploadPart
for _, chunk := range chunks {
fd.Seek(chunk.Offset, os.SEEK_SET)
// Call the UploadPart method to upload each part.
part, err := bucket.UploadPart(imur, fd, chunk.Size, chunk.Number)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
parts = append(parts, part)
}
// Step 3: Complete the multipart upload task.
cmur, err := bucket.CompleteMultipartUpload(imur, parts, oss.GetResponseHeader(&retHeader))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
fmt.Println("cmur:", cmur)
// Display the value of the x-oss-version-id header.
fmt.Println("x-oss-version-id:", oss.GetVersionId(retHeader))
}
References
For more information about the API operation that you can call to perform simple upload, see PutObject.
For more information about the API operation that you can call to perform append upload, see AppendObject.
For more information about the API operation that you can call to complete a multipart upload task, see CompleteMultipartUpload.