前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >腾讯云cos获取文件操作实践--Go SDK

腾讯云cos获取文件操作实践--Go SDK

原创
作者头像
千灵域
发布2022-06-23 21:07:41
4K0
发布2022-06-23 21:07:41
举报
文章被收录于专栏:challenge filterchallenge filter

问题

腾讯云的对象存储可以看做是一个线上的KV,因为最近有需求所以试着用了一下。在使用的时候遇到了一些问题,具体来说是cos.BucketGetOptions中的Delimiter的使用问题。

按官方的说法,delimiter表示列出当前目录下的object,设置为空的时候列出所有的object。我不太清楚这个所有具体是什么意思,因此还是实践了一下。

实践与代码

代码与腾讯cos Go SDK使用学习比较类似,本身应该没有难度。

代码包含以下内容:

  1. 环境构造:通过批量上传文件来构建复杂的文件环境,为后续获取与下载文件提供基础
  2. 文件下载:测试文件内容是否符合预期
  3. 文件批量下载:测试delimiter选项在下载中的影响
  4. 文件列出:测试delimiter选项在文件列出中的影响

环境构造

使用以下函数构造环境,注意:腾讯云对象存储不是免费服务,使用时注意费用情况。本文示例的文件操作理论上不会超过免费限制,但在修改代码的时候请注意。

func main(){
    u, _ := url.Parse("https://wtytest-1252789333.cos.ap-guangzhou.myqcloud.com")
	b := &cos.BaseURL{BucketURL: u}
	c := cos.NewClient(b, &http.Client{
		Transport: &cos.AuthorizationTransport{
			// 通过环境变量获取密钥
			// 环境变量 COS_SECRETID 表示用户的 SecretId,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi
			SecretID: "secretID",
			// 环境变量 COS_SECRETKEY 表示用户的 SecretKey,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi
			SecretKey: "secret",
			// Debug 模式,把对应 请求头部、请求内容、响应头部、响应内容 输出到标准输出
			Transport: &debug.DebugRequestTransport{
				RequestHeader:  true,
				RequestBody:    true,
				ResponseHeader: true,
				ResponseBody:   false,
			},
		},
	})
	// 1. 批量上传文件,构建测试集合
	uploadFileToCos(0, "", c)
}

func uploadFileToCos(depth int, prefix string, c *cos.Client) {
	if depth > 5 {
		return
	}
	for i := 0; i < 3; i++ {
		s := rand.Intn(100)
		filePath := prefix + "file" + strconv.Itoa(s)
		err := uploadFileByName(filePath, "file"+strconv.Itoa(s), c)
		if err != nil {
			log_status(err)
		}
	}

	for i := 0; i < 2; i++ {
		s := rand.Intn(100)
		filePrefix := prefix + "path" + strconv.Itoa(s) + "/"
		uploadFileToCos(depth+1, filePrefix, c)
	}
}

文件下载

// 随便选一个文件名,测试一下是否成功写入
//getFileByName("path59/file81", c)
// 结果为content: file81
func getFileByName(name string, c *cos.Client) {
	resp, err := c.Object.Get(context.Background(), name, nil)
	log_status(err)
	bs, _ := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	fmt.Println("content:", string(bs))
}

文件批量下载

func main(){
	const NoDelimiter = ""
	const FolderDelimiter = "/"
	const path1 = "path59/path33/path43/" // 测试末尾为/
    const path2 = "path59/path33/path43" // 测试末尾不为/
	getAllFileInPrefix(path1, NoDelimiter, c)
	getAllFileInPrefix(path1, FolderDelimiter, c)
}

func getAllFileInPrefix(prefix string, delimiter string, c *cos.Client) {
	totalFileCount := 0
	isTruncated := true
	marker := ""
	count := 0
	for isTruncated {
		fmt.Printf("count:%d marker:%s isTruncated:%v", count, marker, isTruncated)
		count++

		opt := &cos.BucketGetOptions{
			Prefix:    prefix,
			Marker:    marker,
			Delimiter: delimiter,
		}
		v, _, err := c.Bucket.Get(context.Background(), opt)
		if err != nil {
			log_status(err)
			return
		}
		for _, content := range v.Contents {
			resp, err := c.Object.Get(context.Background(), content.Key, nil)
			if err != nil {
				log_status(err)
				return
			}
			bs, _ := ioutil.ReadAll(resp.Body)
			resp.Body.Close()
			fmt.Printf("key:%s content:%s\n", content.Key, string(bs))
			totalFileCount++
		}
		marker = v.NextMarker
		isTruncated = v.IsTruncated
	}
	fmt.Println("total file count is ", totalFileCount, " with count:", count)
}

当cos的键的前缀末尾有"/"时,采用NoDelimiter能获得21个文件,采用FolderDelimiter能获得3个文件。

当cos的键的前缀末尾没有"/"时,采用NoDelimiter能获得21个文件,采用FolderDelimiter能获得0个文件。

这说明delimiter为"/"的时候可以理解为文件夹模式,文件夹模式只对模拟出的文件夹(即前缀末尾有"/")起作用。

如果delimiter为空字符串的时候则会尝试匹配前缀相同的对象。

文件列出

文件列出与文件下载开始的一段逻辑有点类似,不过加上了commonPrefix。测试代码与此前相同,此处不再赘述。

func listAllFileInPrefix(prefix string, delimiter string, c *cos.Client) {
	var marker string
	opt := &cos.BucketGetOptions{
		Prefix:    prefix,
		Delimiter: delimiter,
		MaxKeys:   1000,
	}
	totalFileCount := 0
	commonPrefixCount := 0
	isTruncated := true
	for isTruncated {
		opt.Marker = marker
		v, _, err := c.Bucket.Get(context.Background(), opt)
		if err != nil {
			fmt.Println(err)
			break
		}
		for _, content := range v.Contents {
			fmt.Printf("Object: %v\n", content.Key)
		}
		totalFileCount += len(v.Contents)
		// common prefix表示表示被delimiter截断的路径, 如delimter设置为/, common prefix则表示所有子目录的路径
		for _, commonPrefix := range v.CommonPrefixes {
			fmt.Printf("CommonPrefixes: %v\n", commonPrefix)
		}
		commonPrefixCount += len(v.CommonPrefixes)
		isTruncated = v.IsTruncated // 是否还有数据
		marker = v.NextMarker       // 设置下次请求的起始 key
	}
	fmt.Println("total file count", totalFileCount, " commonPrefix:", commonPrefixCount)
}

当cos的键的前缀末尾有"/"时,采用NoDelimiter能获得21个文件且没有截断路径,采用FolderDelimiter能获得3个文件并截断了2个路径(当前目录下的两个子目录)。

当cos的键的前缀末尾没有"/"时,采用NoDelimiter能获得21个文件且没有截断路径,采用FolderDelimiter能获得0个文件,但是截断了一个路径(path59/path33/path43/)。

总结

对象存储的delimiter可以开启文件夹模式来模拟一般操作系统中的文件夹,总体来说还是比较有用的。

平时不看评论,如果希望和我交流可以发邮件到wtysos11@gmail.com。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题
  • 实践与代码
    • 环境构造
      • 文件下载
        • 文件批量下载
          • 文件列出
          • 总结
          相关产品与服务
          对象存储
          对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档