开发者社区 问答 正文

Go-SDK之如何实现管理文件?

一个Bucket下可能有非常多的文件,SDK提供一系列的接口方便用户管理文件。

列出存储空间中的文件


通过Bucket.ListObjects来列出当前Bucket下的文件。主要的参数如下:

参数说明
Delimiter用于对Object名字进行分组的字符。所有名字包含指定的前缀且第一次出现delimiter字符之间的object作为一组元素CommonPrefixes
Prefix限定返回的object key必须以prefix作为前缀。注意使用prefix查询时,返回的key中仍会包含prefix
MaxKeys限定此次返回object的最大数,如果不设定,默认为100,max-keys取值不能大于1000
Marker设定结果从marker之后按字母排序的第一个开始返回

提示:
  • ListObjects的示例代码在sample/list_objects.go


使用默认参数获取存储空间的文件列表,默认返回100条Objectimport "fmt"
    import "github.com/aliyun/aliyun-oss-go-sdk/oss"

    client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
    if err != nil {
        // HandleError(err)
    }

    bucket, err := client.Bucket("my-bucket")
    if err != nil {
        // HandleError(err)
    }

    lsRes, err := bucket.ListObjects()
    if err != nil {
        // HandleError(err)
    }

    fmt.Println("Objects:", lsRes.Objects)





指定最大返回数量,最多不能超过1000条lsRes, err := bucket.ListObjects(oss.MaxKeys(200))
    if err != nil {
        // HandleError(err)
    }
    fmt.Println("Objects:", lsRes.Objects)





返回指定前缀的Object,默认最多返回100条lsRes, err := bucket.ListObjects(oss.Prefix("my-object-"))
    if err != nil {
        // HandleError(err)
    }
    fmt.Println("Objects:", lsRes.Objects)





指定从某个Object(my-object-xx)后返回,默认最多100条lsRes, err := bucket.ListObjects(oss.Marker("my-object-xx"))
    if err != nil {
        // HandleError(err)
    }
    fmt.Println("Objects:", lsRes.Objects)





分页获取所有Object,每次返回200条marker := oss.Marker("")
    for {
        lsRes, err := bucket.ListObjects(oss.MaxKeys(200), marker)
        if err != nil {
            HandleError(err)
        }
        marker = oss.Marker(lsRes.NextMarker)

        fmt.Println("Objects:", lsRes.Objects)

        if !lsRes.IsTruncated {
            break
        }
    }





分页所有获取从特定Object后的所有的Object,每次返回50条marker = oss.Marker("my-object-xx")
    for {
        lsRes, err := bucket.ListObjects(oss.MaxKeys(50), marker)
        if err != nil {
            // HandleError(err)
        }

        marker = oss.Marker(lsRes.NextMarker)

        fmt.Println("Objects:", lsRes.Objects)

        if !lsRes.IsTruncated {
            break
        }
    }





分页所有获取指定前缀为的Object,每次返回80个。prefix := oss.Prefix("my-object-")
    marker := oss.Marker("")
    for {
        lsRes, err := bucket.ListObjects(oss.MaxKeys(80), marker, prefix)
        if err != nil {
            // HandleError(err)
        }

        prefix = oss.Prefix(lsRes.Prefix)
        marker = oss.Marker(lsRes.NextMarker)

        fmt.Println("Objects:", lsRes.Objects)

        if !lsRes.IsTruncated {
            break
        }
    }





模拟目录结构


OSS是基于对象的存储服务,没有目录的概念。存储在一个Bucket中所有文件都 是通过文件的key唯一标识,并没有层级的结构。这种结构可以让OSS的存储非常 高效,但是用户管理文件时希望能够像传统的文件系统一样把文件分门别类放到 不同的“目录”下面。通过OSS提供的“公共前缀”的功能,也可以很方便地模拟目录 结构。公共前缀的概念请参考 列出Object
假设Bucket中已有如下文件: foo/x
foo/y
foo/bar/a
foo/bar/b
foo/hello/C/1
foo/hello/C/2


通过ListObjects,列出指定目录下的文件和子目录: lsRes, err := bucket.ListObjects(oss.Prefix("foo/"), oss.Delimiter("/"))
    if err != nil {
        // HandleError(err)
    }
    fmt.Println("Objects:", lsRes.Objects,"SubDir:", lsRes.CommonPrefixes)


结果中lsRes.Objects为文件,包括foo/x、foo/y;lsRes.CommonPrefixes即子目录,包括foo/bar/、foo/hello/。

判断文件是否存在


通过Bucket.IsObjectExist来判断文件是否存在。 import "github.com/aliyun/aliyun-oss-go-sdk/oss"

    client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
    if err != nil {
        // HandleError(err)
    }

    bucket, err := client.Bucket("my-bucket")
    if err != nil {
        // HandleError(err)
    }

    isExist, err := bucket.IsObjectExist("my-object")
    if err != nil {
        // HandleError(err)
    }



删除单个文件


通过Bucket.DeleteObject来删除某个文件: import "github.com/aliyun/aliyun-oss-go-sdk/oss"

    client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
    if err != nil {
        // HandleError(err)
    }

    bucket, err := client.Bucket("my-bucket")
    if err != nil {
        // HandleError(err)
    }

    err = bucket.DeleteObject("my-object")
    if err != nil {
        // HandleError(err)
    }



删除多个文件


通过Bucket.DeleteObjects来删除多个文件,用户可以通过DeleteObjectsQuiet参 数来指定是否返回删除的结果。默认返回删除结果。

提示:
  • 删除文件的示例代码在sample/delete_object.go    import "fmt"
  •     import "github.com/aliyun/aliyun-oss-go-sdk/oss"
  •     client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
  •     if err != nil {
  •         // HandleError(err)
  •     }
  •     bucket, err := client.Bucket("my-bucket")
  •     if err != nil {
  •         // HandleError(err)
  •     }
  •     // 默认返回删除成功的文件
  •     delRes, err := bucket.DeleteObjects([]string{"my-object-1", "my-object-2"})
  •     if err != nil {
  •         // HandleError(err)
  •     }
  •     fmt.Println("Deleted Objects:", delRes.DeletedObjects)
  •     // 不返回删除的结果
  •     _, err = bucket.DeleteObjects([]string{"my-object-3", "my-object-4"},
  •         oss.DeleteObjectsQuiet(true))
  •     if err != nil {
  •         // HandleError(err)
  •     }


注意:
  • Bucket.DeleteObjects至少有一个ObjectKey,不能为空。
  • Bucket.DeleteObjects使用的Go的xml包,该包实现了XML1.0标准,XML1.0不支持的特性请不要使用。


获取文件的元信息(Object Meta)


OSS上传/拷贝文件时,除了文件内容,还可以指定文件的一些属性信息,称为“元信息”。这些信息在上传时与文件一起存储,在下载时与文件一起返回。
在SDK中文件元信息用一个Map表示,其他key和value都是string类型,并 且都[backcolor=transparent]只能是简单的ASCII可见字符,不能包含换行。 所有元信息的总大小不 能超过8KB。

注意:
  • 因为文件元信息在上传/下载时是附在HTTP Headers中, HTTP协议规定不能 包含复杂字符。
  • 元数据的名称大小写不敏感,比较/读取时请忽略大小写。

使用Bucket.GetObjectDetailedMeta来获取Object的元信息。

提示:
  • 元信息的示例代码在sample/object_meta.go    import "fmt"
  •     import "github.com/aliyun/aliyun-oss-go-sdk/oss"
  •     client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
  •     if err != nil {
  •         // HandleError(err)
  •     }
  •     bucket, err := client.Bucket("my-bucket")
  •     if err != nil {
  •         // HandleError(err)
  •     }
  •     props, err := bucket.GetObjectDetailedMeta("my-object")
  •     if err != nil {
  •         // HandleError(err)
  •     }
  •     fmt.Println("Object Meta:", props)


提示:
  • Bucket.GetObjectMeta的结果中不包括Object的权限,获取Object权限通过Bucket.GetObjectACL。


修改文件元信息(Object Meta)


用户一次修改一条或多条元信息,可用元信息如下:
元信息说明
CacheControl指定新Object被下载时的网页的缓存行为。
ContentDisposition指定新Object被下载时的名称。
ContentEncoding指定新Object被下载时的内容编码格式。
Expires指定新Object过期时间,建议使用GMT格式。
Meta自定义参数,以"X-Oss-Meta-"为前缀的参数。

使用Bucket.SetObjectMeta来设置Object的元信息。 import "fmt"
    import "github.com/aliyun/aliyun-oss-go-sdk/oss"

    client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
    if err != nil {
        // HandleError(err)
    }

    bucket, err := client.Bucket("my-bucket")
    if err != nil {
        // HandleError(err)
    }

    // 一次修改一条Meta
    err = bucket.SetObjectMeta("my-object", oss.Meta("MyMeta", "MyMetaValue"))
    if err != nil {
        // HandleError(err)
    }

    // 修改多条Meta
    options := []oss.Option{
        oss.Meta("MyMeta", "MyMetaValue"),
        oss.Meta("MyObjectLocation", "HangZhou"),
    }
    err = bucket.SetObjectMeta("my-object", options...)
    if err != nil {
        // HandleError(err)
    }



拷贝文件


使用Bucket.CopyObject或Bucket.CopyObjectToBucket拷贝文件,前者是同一个Bucket内的文件拷贝,后者是Bucket之间的文件拷贝。

提示:
  • 拷贝文件的示例代码在sample/copy_objects.go


同一个Bucket内的文件拷贝import "github.com/aliyun/aliyun-oss-go-sdk/oss"

    client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
    if err != nil {
        // HandleError(err)
    }

    bucket, err := client.Bucket("my-bucket")
    if err != nil {
        // HandleError(err)
    }

    _, err = bucket.CopyObject("my-object", "descObjectKey")
    if err != nil {
        // HandleError(err)
    }





不同Bucket之间的文件拷贝import "github.com/aliyun/aliyun-oss-go-sdk/oss"

    client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
    if err != nil {
        // HandleError(err)
    }

    bucket, err := client.Bucket("my-bucket")
    if err != nil {
        // HandleError(err)
    }

    _, err = bucket.CopyObjectToBucket("my-object", "my-bucket-desc", "descObjectKey")
    if err != nil {
        // HandleError(err)
    }





拷贝时处理文件元信息


文件拷贝(CopyObject/CopyObjectToBucket)时对文件元信息的处理有两种选择,通过MetadataDirective参数指定:
  • oss.MetaCopy 与源文件相同,即拷贝源文件的元信息
  • oss.MetaReplace 使用新的元信息覆盖源文件的信息

默认值是oss.MetaCopy。
COPY时,MetadataDirective为MetaReplace时,用户可以指定新对象的如下的元信息:
元信息说明
CacheControl指定新Object被下载时的网页的缓存行为。
ContentDisposition指定新Object被下载时的名称。
ContentEncoding指定新Object被下载时的内容编码格式。
Expires指定新Object过期时间(seconds)更详细描述请参照RFC2616。
ServerSideEncryption指定OSS创建新Object时的服务器端加密编码算法。
ObjectACL指定OSS创建新Object时的访问权限。
Meta自定义参数,以"X-Oss-Meta-"为前缀的参数。
import (
        "time"
        "github.com/aliyun/aliyun-oss-go-sdk/oss"
    )

    client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
    if err != nil {
        // HandleError(err)
    }

    bucket, err := client.Bucket("my-bucket")
    if err != nil {
        // HandleError(err)
    }

    expires := time.Date(2049, time.January, 10, 23, 0, 0, 0, time.UTC)
    options := []oss.Option{
        oss.MetadataDirective(oss.MetaReplace),
        oss.Expires(expires),
        oss.ObjectACL(oss.ACLPublicRead),
        oss.Meta("MyMeta", "MyMetaValue")}

    _, err = bucket.CopyObject("my-object", "descObjectKey", options...)
    if err != nil {
        // HandleError(err)
    }





限定拷贝条件



文件拷贝时可以设置限定条件,条件满足时拷贝,不满足时报错不拷贝。可以使用的限定条件如下:
参数说明
CopySourceIfMatch如果源Object的ETAG值和用户提供的ETAG相等,则执行拷贝操作;否则返回错误。
CopySourceIfNoneMatch如果源Object的ETAG值和用户提供的ETAG不相等,则执行拷贝操作;否则返回错误。
CopySourceIfModifiedSince如果传入参数中的时间等于或者晚于源文件实际修改时间,则正常拷贝;否则返回错误。
CopySourceIfUnmodifiedSince如果源Object自从用户指定的时间以后被修改过,则执行拷贝操作;否则返回错误。
import (
        "fmt"
        "time"
        "github.com/aliyun/aliyun-oss-go-sdk/oss"
    )

    client, err := oss.New("Endpoint", "AccessKeyId", "AccessKeySecret")
    if err != nil {
        // HandleError(err)
    }

    bucket, err := client.Bucket("my-bucket")
    if err != nil {
        // HandleError(err)
    }

    date := time.Date(2015, time.November, 10, 23, 0, 0, 0, time.UTC)
    // 约束条件不满足,拷贝没有执行
    _, err = bucket.CopyObject("my-object", "descObjectKey", oss.CopySourceIfModifiedSince(date))
    fmt.Println("CopyObjectError:", err)

    // 约束条件满足,拷贝执行
    _, err = bucket.CopyObject("my-object", "descObjectKey", oss.CopySourceIfUnmodifiedSince(date))
    if err != nil {
        // HandleError(err)
    }




提示:
  • Bucket.CopyObject、Bucket.CopyObjectToBucket都支持拷贝时处理文件元信息、限定拷贝条件。

展开
收起
青衫无名 2017-10-19 14:29:40 2035 分享 版权
0 条回答
写回答
取消 提交回答