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

这里写图片描述

项目目录结构:

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

腾讯云COS

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

2、免费额度

这里写图片描述

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

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;
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118

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

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

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

APP_ID=
SECRET_ID=
SECRET_KEY=
bucketName=
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

七牛云存储

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

2、免费额度

这里写图片描述

这里相对于腾讯的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);
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

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

accessKey=
secretKey=
bucket=
 
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3
APP_ID=
SECRET_ID=
SECRET_KEY=
bucketName=
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

各平台的比较

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 {}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这里的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,这点没有自己去实验,只是引出,后期有时间,会贴上实验的结果。


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

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐