最近公司有个需求,需要把本地的文件上传到阿里云。于是就有了这篇博客,记录下来,以免忘记。
阿里云官方文档
这里涉及到AccessKeyId,SecretKeyId,bucket和endPoint这几个常量,这都是从阿里云上创建生成的。
上传文件的主要代码
private OSS initializationOss() {
// 在移动端建议使用STS方式初始化OSSClient。
// 更多信息可查看sample 中 sts
// 使用方式(https://github.com/aliyun/aliyun-oss-android-sdk/tree/master/app/src/main/java/com/alibaba/sdk/android/oss/app)
// OSSCustomSignerCredentialProvider
OSSCustomSignerCredentialProvider ossCustomSignerCredentialProvider = new OSSCustomSignerCredentialProvider() {
@Override public String signContent(String content) {
return OSSUtils.sign(accessKeyId, accessKeySecret, content);
}
};
// 该配置类如果不设置,会有默认配置,具体可看该类
ClientConfiguration conf = new ClientConfiguration();
conf.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒
conf.setSocketTimeout(15 * 1000); // socket超时,默认15秒
conf.setMaxConcurrentRequest(5); // 最大并发请求数,默认5个
conf.setMaxErrorRetry(5); // 失败后最大重试次数,默认2次
// ------>end of log
if (BuildConfig.DEBUG) { // 这里你可根据自己业务需求是否开启阿里云的日志
OSSLog.enableLog();
}
OSS oss = new OSSClient(App.getApplication(), endPoint, ossCustomSignerCredentialProvider);
return oss;
}
注意:上边代码使用的是自签名模式(OSSCustomSignerCredentialProvider),关于自签名和sts鉴权模式,可以访问访问控制,还有就是阿里云不建议在移动端使用OSSPlainTextAKSKCredentialProvider这个类传入到OSSClient构造方法来实例化,具体原因得从阿里云官网找。
下边就是上传代码
private void upload(final String fileName) {
// 构造上传请求
String objectKey = getObjectFileKey(fileName);
if (TextUtils.isEmpty(objectKey)) {
return;
}
// 主要参数就是这三个,分别上传bucketName,然后就是你上传到阿里云的文件夹,最后就是你上传的文件在手机上的路径(包含文件后缀的完成路径)
PutObjectRequest put = new PutObjectRequest(bucketName, objectKey, fileName);
// 异步上传时可以设置进度回调
put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
@Override
public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
}
});
OSSAsyncTask task = initializationOss().asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
@Override public void onSuccess(PutObjectRequest request, PutObjectResult result) {
Log.e("上传日志成功" , fileName);
}
@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(); // 可以等待直到任务完成
}
public String getObjectFileKey(String path) {
String[] pathArrays = path.split("/");
if (pathArrays == null) {
return null;
}
// 这里是根据路径来获取文件夹的名字。
String channelId = pathArrays[pathArrays.length - 2];
String fileName = pathArrays[pathArrays.length - 1];
// 一个/表示创建一个文件夹,这里可以根据自己需求改,不需要跟我这一样,我这的需求是把文件上传到Android文件夹下的channelId文件夹里
return String.format("Android/%s/%s.txt", channelId, fileName);
}
就这么简单。