腾讯云 COS 对象存储 简单文件上传笔记

时间:2024-03-07 11:38:22

这两天用到了腾讯云的 COS对象存储 了(阿里云的对象存储叫:OSS),因此记录一下简单上传的代码,其他的代码后续会逐步上;

COS 对象存储 - 简单文件上传代码:

1、官方文档

  https://cloud.tencent.com/document/product/436/10199


2、SDK

<dependency>
 <groupId>com.qcloud</groupId>
 <artifactId>cos_api</artifactId>
 <version>5.6.24</version>
</dependency>

3、代码 

我使用的是COS的本地文件上传方式,前端传来的文件数据是【MultipartFile】类型的,但是COS在接收本地文件上传时接收的文件数据类型是【File】,因此需要先转一下并生成一个临时的本地文件(生成在服务器端),因此在上传成功后需要删除生成的临时文件,所以,思路很清晰;

  第一步:创建COS连接对象并将【MultipartFile】转化生成一个【File】类型的本地临时文件在服务器上;

  第二步:使用COS连接对象开始上传文件;

  第三步:关闭COS连接、删除本地临时文件;

代码围绕上面的三步如下:

public class COSUploadUtils {

    // 初始化用户身份信息(secretId, secretKey)
    private static String SecretId = "***********";
    private static String SecretKey = "************";
    // bucket的区域
    private static String region_name = "ap-beijing";
    // bucket名
    private static String bucket_name = "****-130*****93";
    // 文件目录
    private static String fileDir = "/***/**/";


    // 将本地文件上传到COS
    public static String SimpleUploadFileFromLocal(MultipartFile file) {
        // 1 初始化用户身份信息(secretId, secretKey)
        COSCredentials cred = new BasicCOSCredentials(SecretId, SecretKey);
        // 2 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
        ClientConfig clientConfig = new ClientConfig(new Region(region_name));
        // 3 生成cos客户端
        COSClient cosclient = new COSClient(cred, clientConfig);


        String originalFilename = file.getOriginalFilename();
        String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
        Random random = new Random();

        String name = System.currentTimeMillis()+"";

        String key = System.currentTimeMillis()+ substring;

        File localFile = null;
        try {
            localFile = new File(key);
            InputStream inputStream = file.getInputStream();
            FileUtils.copyInputStreamToFile(inputStream, localFile);
            localFile = File.createTempFile(name, substring);
            file.transferTo(localFile);
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket_name, fileDir+key, localFile);
        // 设置存储类型, 默认是标准(Standard), 低频(standard_ia)
        putObjectRequest.setStorageClass(StorageClass.Standard);
        String fileName = "";
        try {
            PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest);
            // putobjectResult会返回文件的etag
            String etag = putObjectResult.getETag();
            String crc64 = putObjectResult.getCrc64Ecma();
            fileName = name+substring;
        } catch (CosServiceException e) {
            e.printStackTrace();
        } catch (CosClientException e) {
            e.printStackTrace();
        }

        // 关闭客户端
        cosclient.shutdown();
     
        File f = new File(key);
        if(f.exists()){
            f.delete();
        }
        return fileName;
    }
}

注意事项:

  3.1、在写代码前首先开启腾讯COS服务,并创建存储桶;    

    主要的配置其实也没什么,基本上红框里的填上即可;   

  建议上图中的访问权限选择给【公共读私有写】,因为如果设定私密读的话会在后边的文件访问(他们官方叫:下载)有一定的影响,因为私密读的情况下需要进行签名参数,签名参数中必须要有过期时间设定,存在过期时间的设定就会引发一个问题:缓存,当有了时间设定后的就无法再进行缓存了,因为每次创建一个访问链接都会重新设定一个这个链接的超时时间,每个连接都不同,因此很难在客户端做到缓存的操作,所以,正常情况下设定为【公共读、私有写】即可,当然,如果不考虑缓存的话还是【私有读写】更好一点,无他,安全;

  

  3.2、代码中的COS各个配置信息含义及其获取途径:   

  // 初始化用户身份信息(secretId, secretKey)
    private static String SecretId = "***********";
    private static String SecretKey = "************";

  这个尽量使用子账号进行创建,大概的思路就是【1、创建子用户(权限只针对COS的读写,不赋予任何有关权限的权限);2、在存储桶中配置生成】

    // bucket的区域
    private static String region_name = "ap-beijing";
    // bucket名
    private static String bucket_name = "****-130*****93";
// 文件目录
private static String fileDir = "/***/**/";

  这个是我自定义的参数,很有用,而且COS也是支持这样弄得,主要作用其实就是在上传文件时告诉COS这个文件放在那个文件夹下,也就是文件路径,这个文件路径可以不必提前创建,当你写的路径COS对象存储空间中不存在时它会自动创建出来,而这个路径的使用位置是在上面代码中的:

PutObjectRequest putObjectRequest = new PutObjectRequest(bucket_name, fileDir+key, localFile);

这个是配置好的COS的文件上传对象,

fileDir+key:要拆分成两部分去看1、fileDir,文件所在存储桶的文件路径;2、key:文件最终存到存储桶中的文件名称; 

重要:在创建完存储桶后大家需要注意一下它的安全问题,例如防盗链、服务端加密、容灾容错处理、权限的配置等,在此就不多赘述了;

另外,在写demo时还发现了个小知识点:

  delete 与 deleteOnExit 的区别:

    delete : 删除文件,一旦调用,程序立即执行删除操作;

    deleteOnExit :存在则删除, 它被调用时,相当于对deleteOnExit做了一个生声明, 不会立刻执行删除操作, 而是程序运行结束也就是JVM终止时才真正调用删除操作。即该方法是将删除的命令缓存了一下,到服务停止的时候再进行操作! 


 

上面有什么不太理解的同学可以@我,看到后一定会回复;