上个项目中使用的是阿里云OSS,查阅了官方文档,发现居然没有多文件上传相关说明文档,只有一个单文件异步上传的说明。既没有多文件上传,又没有同步上传,删除文件亦然,凌乱。想到之前做过的七牛云开发,决定用java递归的方式实现多文件同步上传和删除,递归有风险,使用需谨慎哈。
阿里云的配置和初始化官方已经说的很明白了,那么这里就直接了当说关键的:
一般来说我们都是获得多文件对应的本地地址List集合,然后递归每个url进行上传 ---->
/**
* 上传多文件
*
* @param urls
*/
public void uploadFiles(List<String> urls) {
if (null == urls || urls.size() == 0) {
return;
} // 上传文件
ossUpload(urls);
}
下面是阿里云上传递归体----->
/**
* 阿里云OSS上传(默认是异步多文件上传)
* @param urls
*/
private void ossUpload(final List<String> urls) {
if (urls.size() <= 0) {
// 文件全部上传完毕,这里编写上传结束的逻辑,如果要在主线程操作,最好用Handler或runOnUiThead做对应逻辑
return;// 这个return必须有,否则下面报越界异常,原因自己思考下哈
}
final String url = urls.get(0);
if (TextUtils.isEmpty(url)) {
urls.remove(0);
// url为空就没必要上传了,这里做的是跳过它继续上传的逻辑。
ossUpload(urls);
return;
}
File file = new File(url);
if (null == file || !file.exists()) {
urls.remove(0);
// 文件为空或不存在就没必要上传了,这里做的是跳过它继续上传的逻辑。
ossUpload(urls);
return;
}
// 文件后缀
String fileSuffix = "";
if (file.isFile()) {
// 获取文件后缀名
fileSuffix = file.getName().substring(file.getName().lastIndexOf("."));
}
// 文件标识符objectKey
final String objectKey = "alioss_" + System.currentTimeMillis() + fileSuffix;
// 下面3个参数依次为bucket名,ObjectKey名,上传文件路径
PutObjectRequest put = new PutObjectRequest(Constant.BUCKET_NAME, objectKey, url);
// 设置进度回调
put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
@Override
public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
// 进度逻辑
}
});
// 异步上传
OSSAsyncTask task = MyApp.getOSS().asyncPutObject(put,
new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
@Override
public void onSuccess(PutObjectRequest request, PutObjectResult result) { // 上传成功
urls.remove(0);
ossUpload(urls);// 递归同步效果
}
@Override
public void onFailure(PutObjectRequest request, ClientException clientExcepion,
ServiceException serviceException) { // 上传失败
// 请求异常
if (clientExcepion != null) {
// 本地异常如网络异常等
clientExcepion.printStackTrace();
}
if (serviceException != null) {
// 服务异常
Log.e("ErrorCode", serviceException.getErrorCode());
Log.e("RequestId", serviceException.getRequestId());
Log.e("HostId", serviceException.getHostId());
Log.e("RawMessage", serviceException.getRawMessage());
}
}
});
// task.cancel(); // 可以取消任务
// task.waitUntilFinished(); // 可以等待直到任务完成
}
OK,看懂了没,还是蛮简单的,代码注释的也很详细。多文件同步删除与上述上传逻辑属于同一个套路,改几个单词差不多就可以了。这里提醒下,阿里云oss是根据objectKey删除文件的,所以判断文件存不存在是使用官方的代码判断 :
boolean isExist = MyApp.getOSS().doesObjectExist(Constant.BUCKET_NAME, objectKey);
这次就不上传源码了,大家有什么疑问之处或需要源码可以直接回复我。
2017年8月3日更新:
很多朋友都在问我一个请求能不能同时上传多张图片,我这边可能因为没有深入地研究官方文档,不能给大家作出肯定的回复。
But,个人认为没有必要提供这样的接口:首先,多图片一个请求同时上传需要消耗更多的CPU和内存资源(容易造成OOM);其次,漫长时间的网络连接,如果中间出现错误(网络,APP,系统出现问题)不仅前功尽弃,服务端还要删除这些tmp文件。
方案有没有?
这里提供简单的方案思路(基于本文上传方案的修改):
上文提到一个图片上传成功后会回调OSSCompletedCallback的onSuccess方法,那么我们可以在此记录被上传的图片的objectKey于List或Map中,上传结束后把这些objectKey集合通过一个请求反馈给App的服务端就可以了。
Excause Me?! 嗯!就这样!
暂无评论内容