布景:
腾讯云账号下,有许多目标存储COS桶: 我现在想确认某一个目标存储桶的活泼程度,简略的来说。我想知道这个桶里面最终上传的一个文件是什么,以及它的上传时刻戳。 本文将介绍怎么运用腾讯云目标存储(COS)的 Go 言语 SDK 查询指定存储桶中的最新文件信息,包括文件路径和上传时刻。本教程假定读者现已具有根本的 Go 言语编程常识,并且对腾讯云 COS 有一定的了解。
运用腾讯云go sdk 查询目标存储中最新文件
前置条件
- 您需求拥有一个腾讯云账号,并创立了至少一个COS存储桶。
- 了解Go言语和根本的并发编程常识。
- 确保您已装置Go运转时环境。
装置腾讯云COS Go SDK
在开端之前,先确保您的开发环境已装置了腾讯云COS的Go SDK。假如尚未装置,能够运用以下Go指令装置:
mkdir xxxx
go mod int xxxx
go get github.com/tencentyun/cos-go-sdk-v5
咱们这儿的操作是归于List Object 参照:GetBucket
第一版代码:
运用chatgpt生成第一版代码: main.go
package main
import (
"context"
"fmt"
"net/http"
"net/url"
"sort"
"time"
"github.com/tencentyun/cos-go-sdk-v5"
)
// 请替换下面的假定值为实践的 SecretId、SecretKey、BucketName 和 Region。
const (
SecretId = "xxxxxx"
SecretKey = "xxxx"
BucketName = "xxxxxx" // 例如 "example-1250000000"
BucketRegion = "ap-shanghai" // 例如 "ap-guangzhou"
)
func main() {
u, _ := url.Parse(fmt.Sprintf("https://%s.cos.%s.myqcloud.com", BucketName, BucketRegion))
b := &cos.BaseURL{BucketURL: u}
client := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: SecretId,
SecretKey: SecretKey,
},
})
c := context.Background()
opt := &cos.BucketGetOptions{
MaxKeys: 1000, // 修正这个值以获取更多或更少的目标
}
v, _, err := client.Bucket.Get(c, opt)
if err != nil {
panic(err)
}
// 对成果进行排序,找到最终更新的目标
if len(v.Contents) > 0 {
sort.Slice(v.Contents, func(i, j int) bool {
ti, _ := time.Parse(time.RFC3339, v.Contents[i].LastModified)
tj, _ := time.Parse(time.RFC3339, v.Contents[j].LastModified)
return ti.After(tj)
})
lastUpdatedObj := v.Contents[0]
fmt.Printf("最新上传文件路径: %sn", lastUpdatedObj.Key)
fmt.Printf("最新上传时刻: %sn", lastUpdatedObj.LastModified)
} else {
fmt.Println("桶中没有文件。")
}
}
运转main.go
go run main.go
运转后或许感觉是正确的,究竟没有报错。可是这儿是有问题的,为什么呢?因为我本身不知道最终一个文件是什么,我手动上传了一个文件,最终一个文件应该是输出:go1.22.0.linux-amd64.tar.gz! 什么原因呢?问题应该是在这儿:
c := context.Background()
opt := &cos.BucketGetOptions{
MaxKeys: 1000, // 修正这个值以获取更多或更少的目标
}
marker标记参数没有设置 持续修正完善main.go代码:
package main
import (
"context"
"fmt"
"net/http"
"net/url"
"sort"
"time"
"github.com/tencentyun/cos-go-sdk-v5"
)
// 请替换以下的假定值为实践的 SecretId、SecretKey、BucketName 和 Region。
const (
SecretId = "xxxxxx"
SecretKey = "xxxx"
BucketName = "xxxxxx" // 例如 "example-1250000000"
BucketRegion = "ap-shanghai" // 例如 "ap-guangzhou"
)
func main() {
u, _ := url.Parse(fmt.Sprintf("https://%s.cos.%s.myqcloud.com", BucketName, BucketRegion))
b := &cos.BaseURL{BucketURL: u}
client := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: SecretId,
SecretKey: SecretKey,
},
})
c := context.Background()
var lastUpdatedObj *cos.Object
isTruncated := true
nextMarker := ""
for isTruncated {
opt := &cos.BucketGetOptions{
Marker: nextMarker,
MaxKeys: 1000, // 单次恳求回来的最大目标数
}
v, _, err := client.Bucket.Get(c, opt)
if err != nil {
panic(err)
}
for _, object := range v.Contents {
if lastUpdatedObj == nil || object.LastModified > lastUpdatedObj.LastModified {
lastUpdatedObj = &object
}
}
// 更新下一个标记和是否切断的标志
isTruncated = v.IsTruncated
nextMarker = v.NextMarker
}
// 检查是否有目标被找到
if lastUpdatedObj != nil {
fmt.Printf("最新上传文件路径: %sn", lastUpdatedObj.Key)
fmt.Printf("最新上传时刻: %sn", lastUpdatedObj.LastModified)
} else {
fmt.Println("桶中没有文件。")
}
}
运转修正后的main.go文件:
go run main.go
输出go1.22.0.linux-amd64.tar.gz这个最少是正确的!
拆分代码
想持续拆分一下,将客户端的创立和查找逻辑拆分到两个独立的函数createCOSClient getLastUpdatedFileInfo,然后main函数中调用:
package main
import (
"context"
"fmt"
"github.com/tencentyun/cos-go-sdk-v5"
"net/http"
"net/url"
"sort"
"time"
)
// 请替换下面的假定值为实践的 SecretId、SecretKey、BucketName 和 Region。
const (
SecretId = "xxxxxx"
SecretKey = "xxx"
BucketName = "xxxxx" // 例如 "example-1250000000"
BucketRegion = "ap-shanghai" // 例如 "ap-guangzhou"
)
// 创立 COS 客户端
func createCOSClient(secretId, secretKey, bucketName, bucketRegion string) *cos.Client {
u, _ := url.Parse(fmt.Sprintf("https://%s.cos.%s.myqcloud.com", bucketName, bucketRegion))
b := &cos.BaseURL{BucketURL: u}
client := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: secretId,
SecretKey: secretKey,
},
})
return client
}
func getLastUpdatedFileInfo(client *cos.Client) (key, lastModifiedTime string, err error) {
c := context.Background()
// 初始化一个空字符串,表明从桶的开头获取文件列表
nextMarker := ""
var allContents []cos.Object
for {
opt := &cos.BucketGetOptions{
MaxKeys: 1000,
Marker: nextMarker,
}
v, _, err := client.Bucket.Get(c, opt)
if err != nil {
return "", "", err
}
allContents = append(allContents, v.Contents...)
// 假如没有更多的文件,则停止循环
if !v.IsTruncated {
break
}
// 更新 nextMarker 为下一页的开端方位
nextMarker = v.NextMarker
}
// 对所有成果进行排序以找到最新更新的目标
if len(allContents) > 0 {
sort.Slice(allContents, func(i, j int) bool {
ti, errTi := time.Parse(time.RFC3339, allContents[i].LastModified)
tj, errTj := time.Parse(time.RFC3339, allContents[j].LastModified)
if errTi != nil || errTj != nil {
fmt.Printf("Error parsing time: %v, %v", errTi, errTj)
return false
}
return ti.After(tj)
})
lastUpdatedObj := allContents[0]
return lastUpdatedObj.Key, lastUpdatedObj.LastModified, nil
} else {
return "", "", fmt.Errorf("桶中没有文件")
}
}
func main() {
client := createCOSClient(SecretId, SecretKey, BucketName, BucketRegion)
key, lastModifiedTime, err := getLastUpdatedFileInfo(client)
if err != nil {
fmt.Printf("n查询失利: %vn", err)
return
}
fmt.Printf("n最终更新的文件:n")
fmt.Printf("文件路径: %sn", key)
fmt.Printf("最终修正时刻: %sn", lastModifiedTime)
}
运转main.go
go run main.go
注:为了验证代码有效性,我这儿后边又加了一个新的文件:zaZTYa1i2x.txt
加个进展条
上面的代码现已能够正常满意需求了,可是我新加一个进展条,显现查询了多少文件了。也能大概知道一个进展的情况,持续修正一下main.go
package main
import (
"context"
"fmt"
"github.com/tencentyun/cos-go-sdk-v5"
"net/http"
"net/url"
"sort"
"time"
)
// 请替换下面的假定值为实践的 SecretId、SecretKey、BucketName 和 Region。
const (
SecretId = "xxxx"
SecretKey = "xxxxx"
BucketName = "xxxxx" // 例如 "example-1250000000"
BucketRegion = "ap-shanghai" // 例如 "ap-guangzhou"
)
// 创立 COS 客户端
func createCOSClient(secretId, secretKey, bucketName, bucketRegion string) *cos.Client {
u, _ := url.Parse(fmt.Sprintf("https://%s.cos.%s.myqcloud.com", bucketName, bucketRegion))
b := &cos.BaseURL{BucketURL: u}
client := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: secretId,
SecretKey: secretKey,
},
})
return client
}
func getLastUpdatedFileInfo(client *cos.Client) (key, lastModifiedTime string, err error) {
c := context.Background()
nextMarker := ""
var allContents []cos.Object
var retrievedCount int
fmt.Println("开端检索文件列表...")
for {
opt := &cos.BucketGetOptions{
MaxKeys: 10000,
Marker: nextMarker,
}
v, _, err := client.Bucket.Get(c, opt)
if err != nil {
return "", "", err
}
retrievedCount = len(v.Contents)
fmt.Printf("已检索 %d 个文件...r", retrievedCount) // 输出进展信息 'r' 会覆盖当前行,这样咱们就能够在同一行更新进展
allContents = append(allContents, v.Contents...)
if !v.IsTruncated {
break
}
nextMarker = v.NextMarker
}
fmt.Println("n文件列表检索完结。")
if len(allContents) > 0 {
sort.Slice(allContents, func(i, j int) bool {
ti, errTi := time.Parse(time.RFC3339, allContents[i].LastModified)
tj, errTj := time.Parse(time.RFC3339, allContents[j].LastModified)
if errTi != nil || errTj != nil {
fmt.Printf("Error parsing time: %v, %v", errTi, errTj)
return false
}
return ti.After(tj)
})
lastUpdatedObj := allContents[0]
return lastUpdatedObj.Key, lastUpdatedObj.LastModified, nil
} else {
return "", "", fmt.Errorf("桶中没有文件")
}
}
func main() {
client := createCOSClient(SecretId, SecretKey, BucketName, BucketRegion)
key, lastModifiedTime, err := getLastUpdatedFileInfo(client)
if err != nil {
fmt.Printf("n查询失利: %vn", err)
return
}
fmt.Printf("n最终更新的文件:n")
fmt.Printf("文件路径: %sn", key)
fmt.Printf("最终修正时刻: %sn", lastModifiedTime)
}
运转main.go
go run main.go
持续完善
持续完善一下代码:我需求把MaxKeys 提取出来,添加一下输出程序的运转时刻,并把输出文件的时刻戳调整为东八区时刻:
package main
import (
"context"
"fmt"
"github.com/tencentyun/cos-go-sdk-v5"
"net/http"
"net/url"
"sort"
"time"
)
const (
SecretId = "xxxx"
SecretKey = "xxxxx"
BucketName = "xxxxx"
BucketRegion = "ap-shanghai"
MaxKeys = 1000 // 设置最大检索数量的常量
)
var cstZone = time.FixedZone("CST", 8*3600) // 东八区时区
func createCOSClient(secretId, secretKey, bucketName, bucketRegion string) *cos.Client {
u, _ := url.Parse(fmt.Sprintf("https://%s.cos.%s.myqcloud.com", bucketName, bucketRegion))
b := &cos.BaseURL{BucketURL: u}
client := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: secretId,
SecretKey: secretKey,
},
})
return client
}
func getLastUpdatedFileInfo(client *cos.Client) (key, lastModifiedTime string, err error) {
c := context.Background()
nextMarker := ""
var allContents []cos.Object
var retrievedCount int
fmt.Println("开端检索文件列表...")
for {
opt := &cos.BucketGetOptions{
MaxKeys: MaxKeys, // 运用常量 MaxKeys
Marker: nextMarker,
}
v, _, err := client.Bucket.Get(c, opt)
if err != nil {
return "", "", err
}
retrievedCount = len(v.Contents)
fmt.Printf("已检索 %d 个文件...r", retrievedCount)
allContents = append(allContents, v.Contents...)
if !v.IsTruncated {
break
}
nextMarker = v.NextMarker
}
fmt.Println("n文件列表检索完结。")
if len(allContents) > 0 {
sort.Slice(allContents, func(i, j int) bool {
ti, errTi := time.Parse(time.RFC3339, allContents[i].LastModified)
tj, errTj := time.Parse(time.RFC3339, allContents[j].LastModified)
if errTi != nil || errTj != nil {
fmt.Printf("Error parsing time: %v, %v", errTi, errTj)
return false
}
return ti.After(tj)
})
lastUpdatedObj := allContents[0]
// 将文件的 LastModified 时刻字符串转换为 time.Time
t, err := time.Parse(time.RFC3339, lastUpdatedObj.LastModified)
if err != nil {
return "", "", fmt.Errorf("无法解析最终修正时刻: %v", err)
}
// 转换为东八区时刻
cstTime := t.In(cstZone).Format(time.RFC3339)
return lastUpdatedObj.Key, cstTime, nil
} else {
return "", "", fmt.Errorf("桶中没有文件")
}
}
func main() {
start := time.Now() // 程序开端时刻
client := createCOSClient(SecretId, SecretKey, BucketName, BucketRegion)
key, lastModifiedTime, err := getLastUpdatedFileInfo(client)
if err != nil {
fmt.Printf("n查询失利: %vn", err)
return
}
fmt.Printf("n最终更新的文件:n")
fmt.Printf("文件路径: %sn", key)
fmt.Printf("最终修正时刻: %sn", lastModifiedTime)
elapsed := time.Since(start) // 程序执行时刻
fmt.Printf("n程序运转时刻: %sn", elapsed)
}
运转修正后的main.go文件:
go run main.go
持续发散
持续发散一下,我需求输出最终上传的10个文件
package main
import (
"context"
"fmt"
"github.com/tencentyun/cos-go-sdk-v5"
"net/http"
"net/url"
"sort"
"time"
)
// 请替换下面的假定值为实践的 SecretId、SecretKey、BucketName 和 Region。
const (
SecretId = "AKID7Mhwz45A9zqcCf4s07A7FIKKTlAiEf7M"
SecretKey = "KXbXL0unr2EaBsicYejj1GkEjO2jWOAg"
BucketName = "layabox-10028350" // 例如 "example-1250000000"
BucketRegion = "ap-shanghai" // 例如 "ap-guangzhou"
MaxKeys = 1000 // 设置最大检索数量的常量
NumberOfFiles = 10 // 需求获取的最终更新的文件数量
)
var cstZone = time.FixedZone("CST", 8*3600) // 东八区时区
func createCOSClient(secretId, secretKey, bucketName, bucketRegion string) *cos.Client {
u, _ := url.Parse(fmt.Sprintf("https://%s.cos.%s.myqcloud.com", bucketName, bucketRegion))
b := &cos.BaseURL{BucketURL: u}
client := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: secretId,
SecretKey: secretKey,
},
})
return client
}
func getLastUpdatedFileInfo(client *cos.Client, numberOfFiles int) ([]cos.Object, error) {
c := context.Background()
nextMarker := ""
var allContents []cos.Object
var retrievedCount int
fmt.Println("开端检索文件列表...")
for {
opt := &cos.BucketGetOptions{
MaxKeys: MaxKeys, // 运用常量 MaxKeys
Marker: nextMarker,
}
v, _, err := client.Bucket.Get(c, opt)
if err != nil {
return nil, err
}
retrievedCount = len(v.Contents)
fmt.Printf("已检索 %d 个文件...r", retrievedCount)
allContents = append(allContents, v.Contents...)
if !v.IsTruncated {
break
}
nextMarker = v.NextMarker
}
fmt.Println("n文件列表检索完结。")
fmt.Printf("n桶中总文件数: %dn", len(allContents))
if len(allContents) > 0 {
sort.Slice(allContents, func(i, j int) bool {
ti, errTi := time.Parse(time.RFC3339, allContents[i].LastModified)
tj, errTj := time.Parse(time.RFC3339, allContents[j].LastModified)
if errTi != nil || errTj != nil {
fmt.Printf("Error parsing time: %v, %v", errTi, errTj)
return false
}
return ti.After(tj)
})
// 截取切片以获取最终更新的numberOfFiles个文件
if len(allContents) > numberOfFiles {
allContents = allContents[:numberOfFiles]
}
// 回来最终更新的numberOfFiles个文件
return allContents, nil
} else {
return nil, fmt.Errorf("桶中没有文件")
}
}
func main() {
start := time.Now() // 程序开端时刻
client := createCOSClient(SecretId, SecretKey, BucketName, BucketRegion)
files, err := getLastUpdatedFileInfo(client, NumberOfFiles)
if err != nil {
fmt.Printf("n查询失利: %vn", err)
return
}
fmt.Printf("n最终更新的%d个文件:n", NumberOfFiles)
for _, file := range files {
t, err := time.Parse(time.RFC3339, file.LastModified)
if err != nil {
fmt.Printf("无法解析文件 %s 的最终修正时刻: %vn", file.Key, err)
continue
}
cstTime := t.In(cstZone).Format(time.RFC3339)
fmt.Printf("文件路径: %sn", file.Key)
fmt.Printf("最终修正时刻: %sn", cstTime)
}
elapsed := time.Since(start) // 程序执行时刻
fmt.Printf("n程序运转时刻: %sn", elapsed)
}
其实也想过协程或者其他方法?可是奈何max-keys 最大是1000测试了一下没有太大的提升抛弃了……
总结
在这篇博客中,咱们学习了怎么运用腾讯云 COS Go SDK 查询存储桶中最新的文件信息。这包括怎么创立COS客户端,怎么逐页检索目标列表,并怎么对成果排序以找到最终更新的目标。咱们还展示了怎么优化用户体验,经过实时进展更新和检索多个文件来改进程序。
希望本文能协助你在运用腾讯云 COS 时完成更高效的数据管理。