七牛云存储之文件上传
项目中要用到七牛云存储,用于存储用户的文件数据,于是,看了一下七牛的文档(Android SDK 和 Java SDK),写了一个 demo 。本文记录一下 android 端上传文件到七牛服务器的步骤,并对七牛云存储使用的一些问题作出了一些思考。demo 实现了单个文件上传,多个文件上传,多个文件排队上传。详情请参考七牛官方文档。
一,注册七牛账号,并创建存储空间
这里拿到的资源有:AccessKey、SecretKey、bucket,主要是这三个值。
二、Java后台生成上传文件的token
android 端可以添加七牛的 Java SDK,并可以生成 token,但是使用这个 token 上传文件一直提示:no such bucket(具体原因不知道,但是根据密钥安全使用须知,token 是不应该在APP端生成的,所以也没继续找这个问题)。可以在 android studio 新建一个 Java module,添加七牛 Java SDK 依赖,使用 SDK 生成 token,注意这个 token 是有时效的,过来一段时间后会失效,所以每次上传文件前,应该向后台请求一个上传 token,代码如下(根据不同需求,生成 token 所需参数有所变化,详情请看客户端上传凭证):
public static void createQiniuToken() {
String accessKey = "your accesskey";
String secretKey = "your secretkey";
String bucket = "your bucket name";
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
System.out.println(upToken);
}
拿到token之后就可以在 android 端 demo 使用。
三、上传文件到七牛服务器应该考虑或者注意的问题
文件上传到七牛服务器,有很多业务要处理,获取上传凭证(token),文件的命名,文件覆盖,文件管理等。Android SDK 没有提供这些功能,这些功能在 Java SDK 中实现,通过生成不同的 token 实现不同业务功能。
3.1 关于android SDK 上传文件方法中的key
文件的外链接地址是由存储空间的外链域名和key组成的:外链域名 + key,如我的一个bucket的域名为:http://pfln1bbp9.bkt.clouddn.com/ ,那么上传到这个bucket的文件的外链地址为:http://pfln1bbp9.bkt.clouddn.com/ + key。所以,key如何取值,应该有一套自己项目的标准,确保文件何时是唯一的,何时是不唯一的。
3.2 修改或者覆盖文件该如何处理
有些文件可能会修改,那么修改后的文件如何覆盖旧文件呢?
七牛 Android SDK 并没有提供文件的覆盖功能,文件覆盖上传需要服务端的支持,即在生成token的时候带文件的名字,然后拿着这个 token 去上传文件即可:
String accessKey = "access key";
String secretKey = "secret key";
String bucket = "bucket name";
String key = "file key";
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket, key);
System.out.println(upToken);
更多内容请查看 覆盖上传的凭证
3.3 文件的管理功能
文件资源管理属于Java SDK的功能,参考资源管理
3.4 视频/音频/图片压缩功能
七牛支持在文件上传到七牛之后,立即对其进行多种指令的数据处理,这个只需要在生成的上传凭证中指定相关的处理参数即可。
参考 带数据处理的凭证
3.5 文件下载
参考下载文件,值得注意的是在拼接链接之前,将文件名进行urlencode以兼容不同的字符。
3.6 是否支持批量上传
七牛目前只支持一个请求上传一个文件,所以一次上传多个文件的话,就等同于一次发送多个请求,七牛不支持。这正是本文 demo 所要解决的问题。
3.7 密钥安全使用须知
参考密钥安全使用须知
四、Android 端文件上传工具
详情请参考七牛官方文档 对象存储Android SDK。
本 demo 简单实现了七牛文件上传工具:QiniuUploadManager ,这个类提供三个上传文件的方法,和两个取消上传的方法,具体如下:
4.1 单个文件上传
public boolean upload(QiniuUploadFile param, OnUploadListener uploadListener)
4.2 多文件上传
public boolean upload(List<QiniuUploadFile> params, OnUploadListener uploadListener)
4.3 多文件排队上传
public void queueUpload(Queue<QiniuUploadFile> params, OnUploadListener uploadListener)
4.4 取消上传
// 取消某一个listener的任务
public void cancel(OnUploadListener listener)
// 取消所有listener的任务
public void cancel()
4.5 example
private QiniuUploadManager manager;
private String token = "your qiniu upload token";
private void singleUpload(String path) {
if (manager == null) {
manager = QiniuUploadManager.getInstance(this);
}
String currentTim = String.valueOf(System.currentTimeMillis());
String key = "files/" + currentTim + "/" + currentTim + ".jpg";
String mimeType = "image/jpeg";
QiniuUploadManager.QiniuUploadFile param = new QiniuUploadManager.QiniuUploadFile(path, key, mimeType, token);
manager.upload(param, new QiniuUploadManager.OnUploadListener() {
@Override
public void onStartUpload() {
Log.e(TAG, "onStartUpload");
}
@Override
public void onUploadProgress(String key, double percent) {
}
@Override
public void onUploadFailed(String key, String err) {
Log.e(TAG, "onUploadFailed:" + err);
}
@Override
public void onUploadBlockComplete(String key) {
Log.e(TAG, "onUploadBlockComplete");
}
@Override
public void onUploadCompleted() {
Log.e(TAG, "onUploadCompleted");
}
@Override
public void onUploadCancel() {
Log.e(TAG, "onUploadCancel");
}
});
}
4.6 完整代码
import android.content.Context;
import android.util.Log;
import com.qiniu.android.common.FixedZone;
import com.qiniu.android.storage.Configuration;
import com.qiniu.android.storage.KeyGenerator;
import com.qiniu.android.storage.Recorder;
import com.qiniu.android