对象存储服务OSS使用案例之腾讯COS、七牛云存储、阿里OSS

首先放出GitOS的项目地址:https://git.oschina.net/xuliugen/oss-demo.git

对象存储服务OSS使用案例之腾讯COS、七牛云存储、阿里OSS_第1张图片

项目目录结构:

  • ossdemo-aliyunoss:阿里OSS使用案例(尚未完成)
  • ossdemo-qcloudcos :腾讯云COS使用案例
  • ossdemo-qiniu :七牛云存储使用案例 pom.xml

腾讯云COS

1、官方的使用API介绍地址:https://www.qcloud.com/doc/product/227/Java%20SDK

2、免费额度

对象存储服务OSS使用案例之腾讯COS、七牛云存储、阿里OSS_第2张图片

相比目前市场上主流的云存储平台,这个配置对于一般的小型互联网公司来说还是比较有人的地方。

3、项目介绍

对象存储服务OSS使用案例之腾讯COS、七牛云存储、阿里OSS_第3张图片

使用的是:SpringMVC、MyBatis 代码较为简单,主要对CosCloud的一层简单的封装,加载配置信息等操作。下边是QcloudClient的部分代码:

package com.xuliugen.ossdemo.qcloudclient;

import com.qcloud.cosapi.api.CosCloud;
import com.qcloud.cosapi.sign.Sign;
import com.xuliugen.ossdemo.common.constant.QcloudConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.Properties;

/**
 * 自己定义的七牛文件上传Client
 * Created by xuliugen on 16/5/22.
 */
public class QcloudClient {

    private static Properties props = new Properties();
    private static Logger log = LoggerFactory.getLogger(QcloudClient.class);

    static {
        try {
            props.load(QcloudClient.class.getResourceAsStream("/qcloud.properties"));
        } catch (IOException e) {
            log.error("加载配置文件失败", e);
        }
    }

    static int APP_ID = Integer.parseInt(props.getProperty("APP_ID"));
    static String SECRET_ID = props.getProperty("SECRET_ID");
    static String SECRET_KEY = props.getProperty("SECRET_KEY");
    static String bucketName = props.getProperty("bucketName");

    /**
     * 自动判断文件的大小,已使用是否是分片的方式上传文件
     * @param remoteFolderPath 远程文件夹的名称
     * @param loaclPath        文件的本地路径
     * @return
     */
    public static String uploadFile(String remoteFolderPath, String loaclPath) {
        //获取文件输入流
        File f = new File(loaclPath);
        String result = null;
        if (f.exists() && f.isFile()) {
            long size = f.length();
            if (size <= 8 * 1024 * 1024) { //小于等于8M
                result = cosUploadFile(remoteFolderPath + getFileName(loaclPath), loaclPath);
            } else {
                result = sliceUploadFileParallel(remoteFolderPath + getFileName(loaclPath), loaclPath);
            }
        } else {
            System.out.println("file doesn't exist or is not a file");
        }
//        JSONObject retJson = new JSONObject(result);
//        int code = retJson.getInt(ResponseBodyKey.CODE); //文件上传返回码
        //如果错误 封装信息显示
//        return retJson.getString(ResponseBodyKey.MESSAGE); //文件上传返回信息

        return result;
    }

    /**
     * 上传一个长度为10个字节的文件
     * @param remotePath
     * @param loaclPath
     * @return
     */
    public static String cosUploadFile(String remotePath, String loaclPath) {
        CosCloud cos = new CosCloud(APP_ID, SECRET_ID, SECRET_KEY, 60);

        String result = null;
        try {
            result = cos.uploadFile(bucketName, remotePath, loaclPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("uploadFile result:" + result);
        return result;
    }

    /**
     * 串行分片上传文件, 使用默认分片大小
     * @param remotePath
     * @param localPath
     * @return
     */
    public static String sliceUploadFile(String remotePath, String localPath) {
        CosCloud cos = new CosCloud(APP_ID, SECRET_ID, SECRET_KEY, 60);
        String result = null;
        try {
            result = cos.sliceUploadFile(bucketName, remotePath, localPath);
            cos.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("sliceUploadFile result: " + result);
        return result;
    }

    /**
     * 串行分片上传文件, 使用分片大小512KB
     * @param remotePath
     * @param localPath
     * @return
     */
    public static String sliceUploadFileParallel(String remotePath, String localPath) {
        CosCloud cos = new CosCloud(APP_ID, SECRET_ID, SECRET_KEY, 60);
        String result = null;
        try {
            result = cos.sliceUploadFileParallel(bucketName, remotePath, localPath, 512 * 1024);
            cos.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("para sliceUploadFile result: " + result);
        return result;
    }

该Module可以进行单独的部署,和另外两个Module完全独立,便于单独抽出进行使用。

详细代码请到项目中查看。

要修改resources下的qcloud.properties为自己账户下的信息:

APP_ID=
SECRET_ID=
SECRET_KEY=
bucketName=

七牛云存储

1、官方的使用API介绍地址:http://developer.qiniu.com/code/v7/sdk/java.html

2、免费额度

对象存储服务OSS使用案例之腾讯COS、七牛云存储、阿里OSS_第4张图片

这里相对于腾讯的COS空间明显少了很多。

3、项目结构

这个和腾讯云COS的项目结构一样的,不多做解释,使用到的是:

package com.xuliugen.ossdemo.qcloudclient;

import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Properties;

/**
 * 自己定义的七牛文件上传Client
 * Created by xuliugen on 16/5/22.
 */
public class QiniuClient {

    private static Properties props = new Properties();
    private static Logger log = LoggerFactory.getLogger(QiniuClient.class);

    static {
        try {
            props.load(QiniuClient.class.getResourceAsStream("/qiniu.properties"));
        } catch (IOException e) {
            log.error("加载配置文件失败", e);
        }
    }

    static String accessKey = props.getProperty("accessKey");
    static String secretKey = props.getProperty("secretKey");
    static String bucket = props.getProperty("bucket");

    static Auth auth = Auth.create(accessKey, secretKey);

    /**
     * 上传文件到七牛服务器(断点上传)
     * @param key  文件名
     * @param data 文件内容  byte[]
     * @throws Exception
     */
    public static void uploadFile(byte[] data, String key) throws Exception {
        //同名文件覆盖操作、只能上传指定key的文件可以可通过此方法获取token
        String token = auth.uploadToken(bucket, key);
        UploadManager uploadManager = new UploadManager();
        //上传数据
        uploadManager.put(data, key, token);
    }

    /**
     * 从七牛服务器下载文件(获取下载地址)
     * @param key 文件名
     * @throws Exception
     */
    public static String downloadFile(String key) throws Exception {
        return auth.privateDownloadUrl(key, 3600 * 24);
    }

    /**
     * 从七牛服务器删除文件
     * @param key 文件名
     */
    public static void delFile(String key) throws Exception {
        BucketManager bucketManager = new BucketManager(auth);
        bucketManager.delete(bucket, key);
    }
}

要修改resources下的qiniu.properties为自己账户下的信息:

accessKey=
secretKey=
bucket=
APP_ID=
SECRET_ID=
SECRET_KEY=
bucketName=

各平台的比较

1、免费额度的对比
这个刚才上述都已经做了对比,另外阿里云的OSS是没有提供免费额度的,这个免费的服务在2015年的时候据说都已经停止了。

2、API对比

(1)腾讯云COS的上传文件的API有一个很纠结的地方,如下:

    /**
     * 单个文件上传,适用于小文件
     * @param bucketName bucket名称
     * @param remotePath 远程文件路径
     * @param localPath 本地文件路径
     * @return  服务器端返回的操作结果,成员code为0表示成功,具体参照文档手册
     * @throws Exception
     */
    public String uploadFile(String bucketName, String remotePath, String localPath)
        throws Exception {}

这里的remotePath远程文件路径,我原本以为只是一个COS上bucket下需要将该文件上传到的的一个文件夹目录,但是根据官方提供的Demo来看,这个是bucket下你要存储的文件名的路径。
例如:
我有一个文件需要上传,demo.txt bucket 名字为xuliugen4demo 下边有一个文件夹demo,那么remotePath必须要指定为:/demo/demo.txt ,这里的localPath是demo.txt上传到本地的路径,上传到本地服务器之后的位置为:/upload,那么localPath的值就是/upload/demo.txt。

因此,问题来了,我既然在localPath制定了文件的名字,我难道还需要在remotePath中在指定一次吗?

当然这个不是一个大问题,在个人使用的时候,如果,上传的文件存放到cos不需要重命名(设置一个不重复的名称,uuid命名的方式),那么这个参数有一点不理性的地方,如果localPath上传的文件是已经设置为uuid命名的不重复的文件名,那么remotePath的文件名完全可以在localPath的文件名中获取。
这种方式的一个使用地方就是,上传到本地服务器localPath的文件名仍没有改变为不重复的uuid命名,但是上传到cos之后需要进行变更。总的来说,感觉倒不如直接将remotePath设置为cos要上传的文件夹的位置。

(个人意见,可能有没有看到这个方法更多的使用场景。)

另外,对于小文件的上传不支持,直接通过流的方式直接上传,这点事处于文件安全性的问题,但是感觉没有这个方法,对于一些场景下的文件上传,总是先把文件上传到服务器进行存储,找到localPath然后再上传到cos,上传成功之后,然后在进行删除本地的方法,这种方法。。。

另外,腾讯云COS支持文件夹的创建和操作,这个功能很爽,可以根据年月进行文件的分类管理,方便实用,这个是在下边要将的 七牛云中还没有的功能。

(2)七牛云上传文件的方式有一个直接支持文件流上传的方式,其他的都大同小异,很重要的一点是,七牛云上没有看到支持文件夹的API,貌似有点不方便。不过七牛三年的时间 还在慢慢成长。

3、速度对比

网上说的是阿里云的OOS快于腾讯的COS,这点没有自己去实验,只是引出,后期有时间,会贴上实验的结果。


最后,这几个平台正在慢慢摸索,后期会加入对错误的处理,容错,错误重试等方法,个人水平有限,如有建议欢迎留言回复。

你可能感兴趣的:(资源分享)