欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

腾讯云产品系列(一)COS对象存储上传

程序员文章站 2022-03-25 13:07:07
腾讯云---COS对象存储上传前言一、COS对象存储是什么?二、COS对象存储能做什么?1.图文介绍流程2.简单介绍三、COS对象存储怎么使用?1.准备工作2.本文引用javaSDK版本示例3.可能用到的工具类总结前言作者标签:自己选择的路,没有什么后悔的。[1].本文章主要介绍,腾讯云COS对象存储上传文件实例并进行封装。一、COS对象存储是什么?COS对象存储简单来说就是为大家上传文件,处理文件的,开发上传文件到本地会有带宽,占用物理内存等种种限制,所以单独抽出来,进行存储,单独存放...

前言

作者标签:自己选择的路,没有什么后悔的。[1].

本文章主要介绍,腾讯云COS对象存储上传文件实例并进行封装。


一、COS对象存储是什么?

COS对象存储简单来说就是为大家上传文件,处理文件的,开发上传文件到本地会有带宽,占用物理内存等种种限制,所以单独抽出来,进行存储,单独存放到公共资源。

二、COS对象存储能做什么?

1.图文介绍流程

COS 用于数据处理(来自腾讯云官网)

腾讯云产品系列(一)COS对象存储上传

COS 用于内容分发(来自腾讯云官网)

腾讯云产品系列(一)COS对象存储上传

2.简单介绍

对象存储(Cloud Object Storage,COS)是一种存储海量文件的分布式存储服务,用户可通过网络随时存储和查看数据。腾讯云 COS 使所有用户都能使用具备高扩展性、低成本、可靠和安全的数据存储服务。

简单来说,就是可以为大家上传文件提供公共接口,上传到线上资源库,通过腾讯云进行内容分发,用户进行访问。

三、COS对象存储怎么使用?

腾讯云官方文档:https://cloud.tencent.com/document/product/436/38484

1.准备工作

初次使用对象存储 COS,建议您先了解以下基本概念:

  1. 存储桶(bucket):是对象的载体,可理解为存放对象的“容器”。
  2. 对象(Object):是对象存储的基本单元,可理解为任何格式类型的数据,例如图片、文档和音视频文件等。
  3. 地域(Region):是腾讯云托管机房的分布地区,对象存储 COS 的数据存放在这些地域的存储桶中。

2.本文引用javaSDK版本示例

  • 安装sdk依赖
  • 代码如下(示例):
		<!--腾讯云COS-->
		     <dependency>
		         <groupId>com.tencentcloudapi</groupId>
		         <artifactId>tencentcloud-sdk-java</artifactId>
		         <version>3.0.1</version>
		     </dependency>
		     <dependency>
		         <groupId>com.qcloud</groupId>
		         <artifactId>cos_api</artifactId>
		         <version>5.6.8</version>
		     </dependency>
		<!--腾讯云COS-->
  • 封装上传配置配置类
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.region.Region;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @program: cos
 * @description: 存储桶信息配置类
 * @author: Sun
 * @create: 2020-11-19 15:32
 **/

public class TencentCosConfig {
    //存储桶ID
    public static final String COS_APP_ID = "YOUR APPID";
    //存储桶名称
    public static final String COS_BUCKET_NAME = "YOUR BUCKET_NAME";
    //存储桶region名称
    public static final String COS_REGION_NAME = "YOUR REGION_NAME";
    //存储桶密钥id
    public static final String COS_SECRET_ID = "YOUR SECRET_ID";
    //存储桶密钥ley
    public static final String COS_SECRET_KEY = "YOUR SECRET_KEY";
    //存储桶对象Key 前缀
    public static final String COS_RESORCE_PATH="/XXX/xxx/";
    //存储桶访问域名
    public static final String COS_DOMAIN_URL="YOUR DOMAIN_URL";




    /**
     *
     * 方法名称:获取存储桶客户端
     * @return : com.qcloud.cos.COSClient
     * @author : Sun
     * @date : 2020/11/19
     */
    public static COSClient getCosClient(){
        // 1 初始化用户身份信息(secretId, secretKey)。
        COSCredentials cred = new BasicCOSCredentials(COS_SECRET_ID, COS_SECRET_KEY);
        // 2 设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
        // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
        Region region = new Region(COS_REGION_NAME);
        ClientConfig clientConfig = new ClientConfig(region);
        // 3 生成 cos 客户端。
        return new COSClient(cred, clientConfig);
    }

    /**
     *
     * 方法名称:获取对象键(Key)是对象在存储桶中的唯一标识。
     *
     * 功能描述:
     * 〈
     *   获取对象键(Key)是对象在存储桶中的唯一标识。
     *   桶内没有文件架的概念
     *   例如,在对象的访问域名
     *   https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com/images/picture.jpg 中,
     *   对象键为 images/picture.jpg,
     *   对象键就是访问域名后面的所有路径URL  并且唯一
     *  〉
     *
     * @param file 1
     * @param path 2
     * @return : java.lang.String
     * @author : Sun
     * @date : 2020/11/19
     */
    public static String getCosFileKey(MultipartFile file,String path){
        if (StringUtils.isNotNull(path)){
            //模拟路径:/campus/res/sysimg/ + circle/schoo_id/ + xxx.后缀
            return COS_RESORCE_PATH+path+getUniqueFilename(file);
        }
        //模拟路径:/campus/res/sysimg/ + xxx.后缀
        return COS_RESORCE_PATH+getUniqueFilename(file);
    }


    /**
     * 设置:获取唯一文件名字
     */
    private static  String  getUniqueFilename(MultipartFile file)
    {
        String fileName = file.getOriginalFilename();
        String extension = getExtension(file);
        fileName =  IdUtils.fastUUID() + "." + extension;
        return fileName;
    }


    /**
     * 获取文件名的后缀
     *
     * @param file 表单文件
     * @return 后缀名
     */
    private static  String getExtension(MultipartFile file)
    {
        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
        if (StringUtils.isEmpty(extension))
        {
            extension = MimeTypeUtils.getExtension(file.getContentType());
        }
        return extension;
    }


    /**
     *
     * 方法名称:MultipartFile 文件类型转换成File 类型
     *
     * 功能描述:
     * 〈〉
     *
     * @param multipartFile 1
     * @return : java.io.File
     * @author : Sun
     * @date : 2020/11/19
     */
    public static File transferToFile(MultipartFile multipartFile) throws Exception {
        File toFile = null;
        if (multipartFile.equals("") || multipartFile.getSize() <= 0) {
            multipartFile = null;
        } else {
            InputStream ins = null;
            ins = multipartFile.getInputStream();
            toFile = new File(multipartFile.getOriginalFilename());
            inputStreamToFile(ins, toFile);
            ins.close();
        }
        return toFile;
    }

    //获取流文件
    private static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 封装公共上传方法工具类

代码如下(示例):

import java.io.File;

/**
 * @program: cos
 * @description: 腾讯云COS上传文件工具类
 * @author: Sun
 * @create: 2020-11-19 15:30
 **/

public class TencentCosFileUtils {

    /**
     *
     * 方法名称:腾讯COS上传文件方法
     *
     * 功能描述:
     * 〈腾讯COS上传文件方法〉
     *
     * @param multipartFile 文件名称
     * @param path 文件路径/  分类路径 将照片进行分类
     * @return : java.lang.String
     * @author : Sun
     * @date : 2020/11/19
     */
    public static String cosUploadFile(MultipartFile multipartFile, String path) {
        //1.获取存储桶客户端
        COSClient cosClient = TencentCosConfig.getCosClient();
        //2.获取对象key
        String cosFileKey = TencentCosConfig.getCosFileKey(multipartFile,path);
        try {
        //3.将multipartFile转换成FILE类型
        File localFile = TencentCosConfig.transferToFile(multipartFile);
        //4.创建存储对象的请求
        PutObjectRequest putObjectRequest = new PutObjectRequest(TencentCosConfig.COS_BUCKET_NAME, cosFileKey, localFile);
        //5.执行上传并返回结果信息
        PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
        } catch (Exception e){
            System.out.println("-----上传文件出错-----"+e.getMessage());
            e.printStackTrace();
        }finally {
            cosClient.shutdown();
        }
        return TencentCosConfig.COS_DOMAIN_URL+cosFileKey;
    }


    /**
     * 方法名称:删除COS上的文件
     * 功能描述:
     * 〈〉
     * @param filePathUrl 1
     * @return : void
     * @author : Sun
     * @date : 2020/11/19
     */
    public static void cosDeleteFile(String filePathUrl) {
        //1.获取存储桶客户端
        COSClient cosClient = TencentCosConfig.getCosClient();
        try {
        //2.指定要删除的 对象桶 和 对象key
        String[] srr =  filePathUrl.split(TencentCosConfig.COS_DOMAIN_URL);
        String key = srr[1];
        cosClient.deleteObject(TencentCosConfig.COS_BUCKET_NAME, key);
        } catch (Exception e){
            System.out.println("-----上传文件出错-----"+e.getMessage());
            e.printStackTrace();
        }finally {
            cosClient.shutdown();
        }
    }
}

3.可能用到的工具类

  • 字符串工具类

代码如下(示例):

import java.util.Collection;
import java.util.Map;
import com.ruoyi.common.core.text.StrFormatter;

/**
 * 字符串工具类
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils
{
    /** 空字符串 */
    private static final String NULLSTR = "";

    /** 下划线 */
    private static final char SEPARATOR = '_';

    /**
     * 获取参数不为空值
     * 
     * @param value defaultValue 要判断的value
     * @return value 返回值
     */
    public static <T> T nvl(T value, T defaultValue)
    {
        return value != null ? value : defaultValue;
    }

    /**
     * * 判断一个Collection是否为空, 包含List,Set,Queue
     * 
     * @param coll 要判断的Collection
     * @return true:为空 false:非空
     */
    public static boolean isEmpty(Collection<?> coll)
    {
        return isNull(coll) || coll.isEmpty();
    }

    /**
     * * 判断一个Collection是否非空,包含List,Set,Queue
     * 
     * @param coll 要判断的Collection
     * @return true:非空 false:空
     */
    public static boolean isNotEmpty(Collection<?> coll)
    {
        return !isEmpty(coll);
    }

    /**
     * * 判断一个对象数组是否为空
     * 
     * @param objects 要判断的对象数组
     ** @return true:为空 false:非空
     */
    public static boolean isEmpty(Object[] objects)
    {
        return isNull(objects) || (objects.length == 0);
    }

    /**
     * * 判断一个对象数组是否非空
     * 
     * @param objects 要判断的对象数组
     * @return true:非空 false:空
     */
    public static boolean isNotEmpty(Object[] objects)
    {
        return !isEmpty(objects);
    }

    /**
     * * 判断一个Map是否为空
     * 
     * @param map 要判断的Map
     * @return true:为空 false:非空
     */
    public static boolean isEmpty(Map<?, ?> map)
    {
        return isNull(map) || map.isEmpty();
    }

    /**
     * * 判断一个Map是否为空
     * 
     * @param map 要判断的Map
     * @return true:非空 false:空
     */
    public static boolean isNotEmpty(Map<?, ?> map)
    {
        return !isEmpty(map);
    }

    /**
     * * 判断一个字符串是否为空串
     * 
     * @param str String
     * @return true:为空 false:非空
     */
    public static boolean isEmpty(String str)
    {
        return isNull(str) || NULLSTR.equals(str.trim());
    }

    /**
     * * 判断一个字符串是否为非空串
     * 
     * @param str String
     * @return true:非空串 false:空串
     */
    public static boolean isNotEmpty(String str)
    {
        return !isEmpty(str);
    }

    /**
     * * 判断一个对象是否为空
     * 
     * @param object Object
     * @return true:为空 false:非空
     */
    public static boolean isNull(Object object)
    {
        return object == null;
    }

    /**
     * * 判断一个对象是否非空
     * 
     * @param object Object
     * @return true:非空 false:空
     */
    public static boolean isNotNull(Object object)
    {
        return !isNull(object);
    }

    /**
     * * 判断一个对象是否是数组类型(Java基本型别的数组)
     * 
     * @param object 对象
     * @return true:是数组 false:不是数组
     */
    public static boolean isArray(Object object)
    {
        return isNotNull(object) && object.getClass().isArray();
    }

    /**
     * 去空格
     */
    public static String trim(String str)
    {
        return (str == null ? "" : str.trim());
    }

    /**
     * 截取字符串
     * 
     * @param str 字符串
     * @param start 开始
     * @return 结果
     */
    public static String substring(final String str, int start)
    {
        if (str == null)
        {
            return NULLSTR;
        }

        if (start < 0)
        {
            start = str.length() + start;
        }

        if (start < 0)
        {
            start = 0;
        }
        if (start > str.length())
        {
            return NULLSTR;
        }

        return str.substring(start);
    }

    /**
     * 截取字符串
     * 
     * @param str 字符串
     * @param start 开始
     * @param end 结束
     * @return 结果
     */
    public static String substring(final String str, int start, int end)
    {
        if (str == null)
        {
            return NULLSTR;
        }

        if (end < 0)
        {
            end = str.length() + end;
        }
        if (start < 0)
        {
            start = str.length() + start;
        }

        if (end > str.length())
        {
            end = str.length();
        }

        if (start > end)
        {
            return NULLSTR;
        }

        if (start < 0)
        {
            start = 0;
        }
        if (end < 0)
        {
            end = 0;
        }

        return str.substring(start, end);
    }

    /**
     * 格式化文本, {} 表示占位符<br>
     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
     * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
     * 例:<br>
     * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
     * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
     * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
     * 
     * @param template 文本模板,被替换的部分用 {} 表示
     * @param params 参数值
     * @return 格式化后的文本
     */
    public static String format(String template, Object... params)
    {
        if (isEmpty(params) || isEmpty(template))
        {
            return template;
        }
        return StrFormatter.format(template, params);
    }

    /**
     * 下划线转驼峰命名
     */
    public static String toUnderScoreCase(String str)
    {
        if (str == null)
        {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        // 前置字符是否大写
        boolean preCharIsUpperCase = true;
        // 当前字符是否大写
        boolean curreCharIsUpperCase = true;
        // 下一字符是否大写
        boolean nexteCharIsUpperCase = true;
        for (int i = 0; i < str.length(); i++)
        {
            char c = str.charAt(i);
            if (i > 0)
            {
                preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
            }
            else
            {
                preCharIsUpperCase = false;
            }

            curreCharIsUpperCase = Character.isUpperCase(c);

            if (i < (str.length() - 1))
            {
                nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
            }

            if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
            {
                sb.append(SEPARATOR);
            }
            else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
            {
                sb.append(SEPARATOR);
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }

    /**
     * 是否包含字符串
     * 
     * @param str 验证字符串
     * @param strs 字符串组
     * @return 包含返回true
     */
    public static boolean inStringIgnoreCase(String str, String... strs)
    {
        if (str != null && strs != null)
        {
            for (String s : strs)
            {
                if (str.equalsIgnoreCase(trim(s)))
                {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
     * 
     * @param name 转换前的下划线大写方式命名的字符串
     * @return 转换后的驼峰式命名的字符串
     */
    public static String convertToCamelCase(String name)
    {
        StringBuilder result = new StringBuilder();
        // 快速检查
        if (name == null || name.isEmpty())
        {
            // 没必要转换
            return "";
        }
        else if (!name.contains("_"))
        {
            // 不含下划线,仅将首字母大写
            return name.substring(0, 1).toUpperCase() + name.substring(1);
        }
        // 用下划线将原始字符串分割
        String[] camels = name.split("_");
        for (String camel : camels)
        {
            // 跳过原始字符串中开头、结尾的下换线或双重下划线
            if (camel.isEmpty())
            {
                continue;
            }
            // 首字母大写
            result.append(camel.substring(0, 1).toUpperCase());
            result.append(camel.substring(1).toLowerCase());
        }
        return result.toString();
    }

    /**
     * 驼峰式命名法
     * 例如:user_name->userName
     */
    public static String toCamelCase(String s)
    {
        if (s == null)
        {
            return null;
        }
        if (s.indexOf(SEPARATOR) == -1)
        {
            return s;
        }
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++)
        {
            char c = s.charAt(i);

            if (c == SEPARATOR)
            {
                upperCase = true;
            }
            else if (upperCase)
            {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            }
            else
            {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    @SuppressWarnings("unchecked")
    public static <T> T cast(Object obj)
    {
        return (T) obj;
    }
}

  • 媒体类型工具类
/**
 * 媒体类型工具类
 */
public class MimeTypeUtils
{
    public static final String IMAGE_PNG = "image/png";

    public static final String IMAGE_JPG = "image/jpg";

    public static final String IMAGE_JPEG = "image/jpeg";

    public static final String IMAGE_BMP = "image/bmp";

    public static final String IMAGE_GIF = "image/gif";

    public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" };

    public static final String[] FLASH_EXTENSION = { "swf", "flv" };

    public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
            "asf", "rm", "rmvb" };

    public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" };

    public static final String[] DEFAULT_ALLOWED_EXTENSION = {
            // 图片
            "bmp", "gif", "jpg", "jpeg", "png",
            // word excel powerpoint
            "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
            // 压缩文件
            "rar", "zip", "gz", "bz2",
            // 视频格式
            "mp4", "avi", "rmvb",
            // pdf
            "pdf" };

    public static String getExtension(String prefix)
    {
        switch (prefix)
        {
            case IMAGE_PNG:
                return "png";
            case IMAGE_JPG:
                return "jpg";
            case IMAGE_JPEG:
                return "jpeg";
            case IMAGE_BMP:
                return "bmp";
            case IMAGE_GIF:
                return "gif";
            default:
                return "";
        }
    }
}

  • ID生成器工具类
/**
 * ID生成器工具类
 *
 */
public class IdUtils
{
    /**
     * 获取随机UUID
     * 
     * @return 随机UUID
     */
    public static String randomUUID()
    {
        return UUID.randomUUID().toString();
    }

    /**
     * 简化的UUID,去掉了横线
     * 
     * @return 简化的UUID,去掉了横线
     */
    public static String simpleUUID()
    {
        return UUID.randomUUID().toString(true);
    }

    /**
     * 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID
     * 
     * @return 随机UUID
     */
    public static String fastUUID()
    {
        return UUID.fastUUID().toString();
    }

    /**
     * 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID
     * 
     * @return 简化的UUID,去掉了横线
     */
    public static String fastSimpleUUID()
    {
        return UUID.fastUUID().toString(true);
    }
}

  • 测试接口
 @PostMapping("/testUploadFile")
    @ResponseBody
    public String testUploadFile(MultipartFile file, Integer yourUserId)
    {
        try
        {
            // 上传文件分类路径
            String filePath =yourUserId+"/";
            // 上传文件返回全路径
            String cosFilePathUrl = TencentCosFileUtils.cosUploadFile(file, filePath);
            return cosFilePathUrl;
        }
        catch (Exception e)
        {
            return e.getMessage();
        }
    }

总结

以上就是对腾讯云COS的讲解和通过COS进行文件上传的封装。谢谢大家的观看,抽空点个赞呗~

本文地址:https://blog.csdn.net/weixin_43833970/article/details/109842973