列举多版本对象

更新时间: 2019-03-14 10:05

您可以通过ObsClient.ListVersions列举多版本对象。

该接口可设置的参数如下:


参数

作用

ListVersionsInput.Bucket

桶名。

ListVersionsInput.Prefix

限定返回的对象名必须带有Prefix前缀。

ListVersionsInput.KeyMarker

列举多版本对象的起始位置,返回的对象列表将是对象名按照字典序排序后该参数以后的所有对象。

ListVersionsInput.MaxKeys

列举多版本对象的最大数目,取值范围为1~1000,当超出范围时,按照默认的1000进行处理。

ListVersionsInput.Delimiter

用于对对象名进行分组的字符。对于对象名中包含Delimiter的对象,其对象名(如果请求中指定了Prefix,则此处的对象名需要去掉Prefix)中从首字符至第一个Delimiter之间的字符串将作为一个分组并作为CommonPrefix返回。

ListVersionsInput.VersionIdMarker

与Delimiter配合使用,返回的对象列表将是对象名和版本号按照字典序排序后该参数以后的所有对象。

列举多版本对象 - 图1 说明:

  • 如果VersionIdMarker不是KeyMarker的一个版本号,则该参数无效。
  • ObsClient.ListVersions返回结果包含多版本对象和对象删除标记。

简单列举

以下代码展示如何简单列举多版本对象,最多返回1000个对象:

  1. // 引入依赖包
  2. import (
  3. "fmt"
  4. "obs"
  5. )
  6.  
  7. var ak = "*** Provide your Access Key ***"
  8. var sk = "*** Provide your Secret Key ***"
  9. var endpoint = "https://your-endpoint"
  10.  
  11. // 创建ObsClient结构体
  12. var obsClient, _ = obs.New(ak, sk, endpoint)
  13.  
  14. func main() {
  15. input := &obs.ListVersionsInput{}
  16. input.Bucket = "bucketname"
  17. output, err := obsClient.ListVersions(input)
  18. if err == nil {
  19. // 获取多版本对象
  20. for index, val := range output.Versions {
  21. fmt.Printf("Version[%d]-OwnerId:%s, ETag:%s, Key:%s, VersionId:%s, LastModified:%s, Size:%d\n",
  22. index, val.Owner.ID, val.ETag, val.Key, val.VersionId, val.LastModified, val.Size)
  23. }
  24. // 获取对象删除标记
  25. for index, val := range output.DeleteMarkers {
  26. fmt.Printf("DeleteMarker[%d]-OwnerId:%s, OwnerName:%s, Key:%s, VersionId:%s, LastModified:%s\n",
  27. index, val.Owner.ID, val.Owner.DisplayName, val.Key, val.VersionId, val.LastModified)
  28. }
  29. } else if obsError, ok := err.(obs.ObsError); ok {
  30. fmt.Printf("Code:%s\n", obsError.Code)
  31. fmt.Printf("Message:%s\n", obsError.Message)
  32. }
  33. }

列举多版本对象 - 图2 说明:

  • 每次至多返回1000个多版本对象,如果指定桶包含的对象数量大于1000,则返回结果中ListVersionsOutput.IsTruncated为true表明本次没有返回全部对象,并可通过ListVersionsOutput.NextKeyMarker和ListVersionsOutput.NextVersionIdMarker获取下次列举的起始位置。
  • 如果想获取指定桶包含的所有多版本对象,可以采用分页列举的方式。

指定数目列举

以下代码展示如何指定数目列举多版本对象:

  1. // 引入依赖包
  2. import (
  3. "fmt"
  4. "obs"
  5. )
  6.  
  7. var ak = "*** Provide your Access Key ***"
  8. var sk = "*** Provide your Secret Key ***"
  9. var endpoint = "https://your-endpoint"
  10.  
  11. // 创建ObsClient结构体
  12. var obsClient, _ = obs.New(ak, sk, endpoint)
  13.  
  14. func main() {
  15. input := &obs.ListVersionsInput{}
  16. input.Bucket = "bucketname"
  17. // 列举100个多版本对象
  18. input.MaxKeys = 100
  19. output, err := obsClient.ListVersions(input)
  20. if err == nil {
  21. // 获取多版本对象
  22. for index, val := range output.Versions {
  23. fmt.Printf("Version[%d]-OwnerId:%s, ETag:%s, Key:%s, VersionId:%s, LastModified:%s, Size:%d\n",
  24. index, val.Owner.ID, val.ETag, val.Key, val.VersionId, val.LastModified, val.Size)
  25. }
  26. // 获取对象删除标记
  27. for index, val := range output.DeleteMarkers {
  28. fmt.Printf("DeleteMarker[%d]-OwnerId:%s, Key:%s, VersionId:%s, LastModified:%s\n",
  29. index, val.Owner.ID, val.Key, val.VersionId, val.LastModified)
  30. }
  31. } else if obsError, ok := err.(obs.ObsError); ok {
  32. fmt.Printf("Code:%s\n", obsError.Code)
  33. fmt.Printf("Message:%s\n", obsError.Message)
  34. }
  35. }

指定前缀列举

以下代码展示如何指定前缀列举多版本对象:

  1. // 引入依赖包
  2. import (
  3. "fmt"
  4. "obs"
  5. )
  6.  
  7. var ak = "*** Provide your Access Key ***"
  8. var sk = "*** Provide your Secret Key ***"
  9. var endpoint = "https://your-endpoint"
  10.  
  11. // 创建ObsClient结构体
  12. var obsClient, _ = obs.New(ak, sk, endpoint)
  13.  
  14. func main() {
  15. input := &obs.ListVersionsInput{}
  16. input.Bucket = "bucketname"
  17. // 设置列举带有prefix前缀的100个多版本对象
  18. input.MaxKeys = 100
  19. input.Prefix = "prefix"
  20. output, err := obsClient.ListVersions(input)
  21. if err == nil {
  22. // 获取多版本对象
  23. for index, val := range output.Versions {
  24. fmt.Printf("Version[%d]-OwnerId:%s, ETag:%s, Key:%s, VersionId:%s, LastModified:%s, Size:%d\n",
  25. index, val.Owner.ID, val.ETag, val.Key, val.VersionId, val.LastModified, val.Size)
  26. }
  27. // 获取对象删除标记
  28. for index, val := range output.DeleteMarkers {
  29. fmt.Printf("DeleteMarker[%d]-OwnerId:%s, Key:%s, VersionId:%s, LastModified:%s\n",
  30. index, val.Owner.ID, val.Key, val.VersionId, val.LastModified)
  31. }
  32. } else if obsError, ok := err.(obs.ObsError); ok {
  33. fmt.Printf("Code:%s\n", obsError.Code)
  34. fmt.Printf("Message:%s\n", obsError.Message)
  35. }
  36. }

指定起始位置列举

以下代码展示如何指定起始位置列举多版本对象:

  1. // 引入依赖包
  2. import (
  3. "fmt"
  4. "obs"
  5. )
  6.  
  7. var ak = "*** Provide your Access Key ***"
  8. var sk = "*** Provide your Secret Key ***"
  9. var endpoint = "https://yourdomainname"
  10.  
  11. // 创建ObsClient结构体
  12. var obsClient, _ = obs.New(ak, sk, endpoint)
  13.  
  14. func main() {
  15. input := &obs.ListVersionsInput{}
  16. input.Bucket = "bucketname"
  17. // 设置列举对象名字典序在"test"之后的100个多版本对象
  18. input.MaxKeys = 100
  19. input.Marker = "test"
  20. output, err := obsClient.ListVersions(input)
  21. if err == nil {
  22. // 获取多版本对象
  23. for index, val := range output.Versions {
  24. fmt.Printf("Version[%d]-OwnerId:%s, ETag:%s, Key:%s, VersionId:%s, LastModified:%s, Size:%d\n",
  25. index, val.Owner.ID, val.Owner.DisplayName, val.ETag, val.Key, val.VersionId, val.LastModified, val.Size)
  26. }
  27. // 获取对象删除标记
  28. for index, val := range output.DeleteMarkers {
  29. fmt.Printf("DeleteMarker[%d]-OwnerId:%s, Key:%s, VersionId:%s, LastModified:%s\n",
  30. index, val.Owner.ID, val.Key, val.VersionId, val.LastModified)
  31. }
  32. } else if obsError, ok := err.(obs.ObsError); ok {
  33. fmt.Printf("Code:%s\n", obsError.Code)
  34. fmt.Printf("Message:%s\n", obsError.Message)
  35. }
  36. }

分页列举全部多版本对象

以下代码展示分页列举全部多版本对象:

  1. // 引入依赖包
  2. import (
  3. "fmt"
  4. "obs"
  5. )
  6.  
  7. var ak = "*** Provide your Access Key ***"
  8. var sk = "*** Provide your Secret Key ***"
  9. var endpoint = "https://your-endpoint"
  10.  
  11. // 创建ObsClient结构体
  12. var obsClient, _ = obs.New(ak, sk, endpoint)
  13.  
  14. func main() {
  15. input := &obs.ListVersionsInput{}
  16. input.Bucket = "bucketname"
  17. input.MaxKeys = 100
  18. index := 1
  19. for {
  20. output, err := obsClient.ListVersions(input)
  21. if err == nil {
  22. fmt.Printf("Page:%d", index)
  23. index++
  24. // 获取多版本对象
  25. for index, val := range output.Versions {
  26. fmt.Printf("Version[%d]-OwnerId:%s, ETag:%s, Key:%s, VersionId:%s, LastModified:%s, Size:%d\n",
  27. index, val.Owner.ID, val.ETag, val.Key, val.VersionId, val.LastModified, val.Size)
  28. }
  29. // 获取对象删除标记
  30. for index, val := range output.DeleteMarkers {
  31. fmt.Printf("DeleteMarker[%d]-OwnerId:%s, Key:%s, VersionId:%s, LastModified:%s\n",
  32. index, val.Owner.ID, val.Key, val.VersionId, val.LastModified)
  33. }
  34. if output.IsTruncated {
  35. input.KeyMarker = output.NextKeyMarker
  36. input.VersionIdMarker = output.NextVersionIdMarker
  37. } else {
  38. break
  39. }
  40. } else {
  41. if obsError, ok := err.(obs.ObsError); ok {
  42. fmt.Printf("Code:%s\n", obsError.Code)
  43. fmt.Printf("Message:%s\n", obsError.Message)
  44. }
  45. break
  46. }
  47. }
  48. }

列举文件夹中的所有多版本对象

OBS本身是没有文件夹的概念的,桶中存储的元素只有对象。文件夹对象实际上是一个大小为0且对象名以“/”结尾的对象,将这个文件夹对象名作为前缀,即可模拟列举文件夹中对象的功能。以下代码展示如何列举文件夹中的多版本对象:

  1. // 引入依赖包
  2. import (
  3. "fmt"
  4. "obs"
  5. )
  6.  
  7. var ak = "*** Provide your Access Key ***"
  8. var sk = "*** Provide your Secret Key ***"
  9. var endpoint = "https://your-endpoint"
  10.  
  11. // 创建ObsClient结构体
  12. var obsClient, _ = obs.New(ak, sk, endpoint)
  13.  
  14. func main() {
  15. input := &obs.ListVersionsInput{}
  16. input.Bucket = "bucketname"
  17. input.MaxKeys = 100
  18. // 设置根目录"dir/"
  19. input.Prefix = "dir/"
  20. for {
  21. output, err := obsClient.ListVersions(input)
  22. if err == nil {
  23. // 获取多版本对象
  24. for index, val := range output.Versions {
  25. fmt.Printf("Version[%d]-OwnerId:%s, ETag:%s, Key:%s, VersionId:%s, LastModified:%s, Size:%d\n",
  26. index, val.Owner.ID, val.ETag, val.Key, val.VersionId, val.LastModified, val.Size)
  27. }
  28. // 获取对象删除标记
  29. for index, val := range output.DeleteMarkers {
  30. fmt.Printf("DeleteMarker[%d]-OwnerId:%s, Key:%s, VersionId:%s, LastModified:%s\n",
  31. index, val.Owner.ID, val.Key, val.VersionId, val.LastModified)
  32. }
  33. if output.IsTruncated {
  34. input.KeyMarker = output.NextKeyMarker
  35. input.VersionIdMarker = output.NextVersionIdMarker
  36. } else {
  37. break
  38. }
  39. } else {
  40. if obsError, ok := err.(obs.ObsError); ok {
  41. fmt.Printf("Code:%s\n", obsError.Code)
  42. fmt.Printf("Message:%s\n", obsError.Message)
  43. }
  44. break
  45. }
  46. }
  47. }

按文件夹分组列举所有多版本对象

以下代码展示如何按文件夹分组,列举桶内所有多版本对象:

  1. // 引入依赖包
  2. import (
  3. "fmt"
  4. "obs"
  5. )
  6.  
  7. var ak = "*** Provide your Access Key ***"
  8. var sk = "*** Provide your Secret Key ***"
  9. var endpoint = "https://your-endpoint"
  10.  
  11. // 创建ObsClient结构体
  12. var obsClient, _ = obs.New(ak, sk, endpoint)
  13.  
  14. func listVersionsByPrefix(output *obs.ListVersionsOutput) {
  15. input := &obs.ListVersionsInput{}
  16. input.Bucket = "bucketname"
  17. // 设置文件夹分隔符
  18. input.Delimiter = "/"
  19. for _, commonPrefix := range output.CommonPrefixes {
  20. input.Prefix = commonPrefix
  21. output, err := obsClient.ListVersions(input)
  22. if err == nil {
  23. fmt.Printf("Objects in folder [%s]:\n", commonPrefix)
  24. // 获取多版本对象
  25. for index, val := range output.Versions {
  26. fmt.Printf("Version[%d]-OwnerId:%s, ETag:%s, Key:%s, VersionId:%s, LastModified:%s, Size:%d\n",
  27. index, val.Owner.ID, val.ETag, val.Key, val.VersionId, val.LastModified, val.Size)
  28. }
  29. // 获取对象删除标记
  30. for index, val := range output.DeleteMarkers {
  31. fmt.Printf("DeleteMarker[%d]-OwnerId:%s, Key:%s, VersionId:%s, LastModified:%s\n",
  32. index, val.Owner.ID, val.Key, val.VersionId, val.LastModified)
  33. }
  34. listVersionsByPrefix(output)
  35. } else if obsError, ok := err.(obs.ObsError); ok {
  36. fmt.Printf("Code:%s\n", obsError.Code)
  37. fmt.Printf("Message:%s\n", obsError.Message)
  38. }
  39. }
  40. }
  41.  
  42. func main() {
  43. input := &obs.ListVersionsInput{}
  44. input.Bucket = "bucketname"
  45. // 设置文件夹分隔符
  46. input.Delimiter = "/"
  47. output, err := obsClient.ListVersions(input)
  48.  
  49. if err == nil {
  50. fmt.Println("Objects in the root directory:")
  51. // 获取多版本对象
  52. for index, val := range output.Versions {
  53. fmt.Printf("Version[%d]-OwnerId:%s, ETag:%s, Key:%s, VersionId:%s, LastModified:%s, Size:%d\n",
  54. index, val.Owner.ID, val.ETag, val.Key, val.VersionId, val.LastModified, val.Size)
  55. }
  56. // 获取对象删除标记
  57. for index, val := range output.DeleteMarkers {
  58. fmt.Printf("DeleteMarker[%d]-OwnerId:%s, Key:%s, VersionId:%s, LastModified:%s\n",
  59. index, val.Owner.ID, val.Key, val.VersionId, val.LastModified)
  60. }
  61. listVersionsByPrefix(output)
  62. } else if obsError, ok := err.(obs.ObsError); ok {
  63. fmt.Printf("Code:%s\n", obsError.Code)
  64. fmt.Printf("Message:%s\n", obsError.Message)
  65. }
  66. }

列举多版本对象 - 图3 说明:

  • 以上代码示例没有考虑文件夹中多版本对象数超过1000个的情况。
  • 由于是需要列举出文件夹中的对象和子文件夹,且文件夹对象总是以“/”结尾,因此Delimiter总是为“/”。
  • 每次递归的返回结果中ListVersionsOutput.Versions包含的是文件夹中的多版本对象;ListVersionsOutput.DeleteMarkers包含的是文件夹中的删除标记;ListVersionsOutput.CommonPrefixes包含的是文件夹的子文件夹。

父主题:多版本控制