上传Object
最简单的上传
基本流程
- 创建BOSClient 类的实例。
- 调用BOSClient.putObject()方法,可以通过如下四种方式上传Object:文件、数据流、二进制串和字符串的形式。
- 对返回的PutObjectResponse类型实例,执行getETag()获得上传成功的ETag。
示例代码
// 获取指定文件
File file = new File(<FilePath>); //指定文件路径
// 以文件形式上传Object
PutObjectResponse putObjectFromFileResponse =
client.putObject(<BucketName>, <ObjectKey>, file);
// 获取数据流
InputStream inputStream = new FileInputStream(<FilePath>);
// 以数据流形式上传Object
PutObjectResponse putObjectResponseFromInputStream =
client.putObject(<BucketName>, <ObjectKey>, inputStream);
// 以二进制串上传Object
PutObjectResponse putObjectResponseFromByte =
client.putObject(<BucketName>, <ObjectKey>, <byte>);
// 以字符串上传Object
PutObjectResponse putObjectResponseFromString =
client.putObject(<BucketName>, <ObjectKey>, <string>);
// 打印ETag
System.out.println(putObjectFromFileResponse.getETag());
说明:Object以文件的形式上传到BOS中,putObject函数支持不超过5GB的Object上传。在putObject请求处理成功后,BOS会在Header中返回Object的ETag作为文件标识。
完整示例
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import android.app.Activity;
import android.os.Bundle;
import com.baidubce.BceClientException;
import com.baidubce.BceServiceException;
import com.baidubce.auth.DefaultBceCredentials;
import com.baidubce.development.R;
import com.baidubce.services.bos.BosClient;
import com.baidubce.services.bos.BosClientConfiguration;
import com.baidubce.services.bos.model.PutObjectResponse;
public class ExampleActivity extends Activity {
private String bucketName = <BucketName>;
private String objectKey = <ObjectKey>;
byte[] b = null;
String str = <PutString>;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
try {
BosClientConfiguration config = new BosClientConfiguration();
config.setCredentials(new DefaultBceCredentials(<AccessKeyID>, <SecretAccessKey>));
config.setEndpoint(<EndPoint>);
BosClient client = new BosClient(config);
// 获取指定文件
File file = new File("/path/to/file.zip");
// 以文件形式上传Object
PutObjectResponse putObjectFromFileResponse = client.putObject(<BucketName>, <ObjectKey>, file);
// 获取数据流
InputStream inputStream = new FileInputStream("/path/to/test.zip");
// 以数据流形式上传Object
PutObjectResponse putObjectResponseFromInputStream = client.putObject(<BucketName>, <ObjectKey>, inputStream);
// 以二进制串上传Object
PutObjectResponse putObjectResponseFromByte = client.putObject(<BucketName>, <ObjectKey>, b);
// 以字符串上传Object
PutObjectResponse putObjectResponseFromString = client.putObject(<BucketName>, <ObjectKey>, str);
// 打印ETag
System.out.println(putObjectFromFileResponse.getETag());
} catch (BceServiceException e) {
System.out.println("Error ErrorCode: " + e.getErrorCode());
System.out.println("Error RequestId: " + e.getRequestId());
System.out.println("Error StatusCode: " + e.getStatusCode());
System.out.println("Error Message: " + e.getMessage());
System.out.println("Error ErrorType: " + e.getErrorType());
} catch (BceClientException e) {
System.out.println("Error Message: " + e.getMessage());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}}
设定Object的Copy属性
CopyObject接口用于将一个已经存在的Object拷贝到另外一个Object,拷贝过程中会对源Object的Etag或修改状态进行判断,根据判断结果决定是否执行拷贝。详细的参数解释如下:
名称 | 类型 | 描述 | 是否必需 |
---|---|---|---|
x-bce-copy-source-if-match | String | 如果源Object的ETag值和用户提供的ETag相等,则执行拷贝操作,否则拷贝失败。 | 否 |
x-bce-copy-source-if-none-match | String | 如果源Object的ETag和用户提供的ETag不相等,则执行拷贝操作,否则拷贝失败。 | 否 |
x-bce-copy-source-if-unmodified-since | String | 如果源object在x-bce-copy-source-if-unmodified-since之后没被修改,则执行拷贝操作,否则拷贝失败。 | 否 |
x-bce-copy-source-if-modified-since | String | 如果源object在x-bce-copy-source-if-modified-since之后被修改了,则执行拷贝操作,否则拷贝失败。 | 否 |
示例代码
// 初始化BosClient
BosClient client = ...;
// 创建CopyObjectRequest对象
CopyObjectRequest copyObjectRequest = new CopyObjectRequest(srcBucketName, srcKey, destBucketName, destKey);
// 设置新的Metadata
Map<String, String> userMetadata = new HashMap<String, String>();
userMetadata.put("<user-meta-key>","<user-meta-value>");
ObjectMetadata meta = new ObjectMetadata();
meta.setUserMetadata(userMetadata);
copyObjectRequest.setNewObjectMetadata(meta);
//copy-source-if-match
copyObjectRequest.withETag("111111111183bf192b57a4afc76fa632");
//copy-source-if-none-match
copyObjectRequest.withNoMatchingETagConstraint("111111111183bf192b57a4afc76fa632");
Date modifiedSinceConstraint = new Date();
SimpleDateFormat df = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.UK);
df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));
String date = df.format(modifiedSinceConstraint);
//copy-source-if-modified-since
copyObjectRequest.withModifiedSinceConstraint(date);
//copy-source-if-unmodified-since
copyObjectRequest.withUnmodifiedSinceConstraint(date);
// 复制Object
CopyObjectResponse copyObjectResponse = client.copyObject(copyObjectRequest);
设定Object的Http Header
BOS支持您在上传object时设定Http Header。
基本流程
- 创建ObjectMetadata类的实例。
- 执行setContentLength()/setContentType()等方法对Http Header进行设定。
- 将设定后的meta作为参数加入client.putObject()中。
示例代码
// 创建ObjectMetadata类的实例
ObjectMetadata meta = new ObjectMetadata();
// 设置ContentLength大小
meta.setContentLength(<Length>);
// 设置ContentType
meta.setContentType("application/json");
client.putObject(<BucketName>, <ObjectKey>, content, meta);
说明:header可设置的属性有:"Cache-Control"、"Content-Encoding"、"Content-Disposition"、"Expires"
完整示例
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import android.app.Activity;
import android.os.Bundle;
import com.baidubce.BceClientException;
import com.baidubce.BceServiceException;
import com.baidubce.auth.DefaultBceCredentials;
import com.baidubce.demo.R;
import com.baidubce.services.bos.BosClient;
import com.baidubce.services.bos.BosClientConfiguration;
import com.baidubce.services.bos.model.ObjectMetadata;
import com.baidubce.services.bos.model.PutObjectResponse;
public class ExampleActivity extends Activity {
private String bucketName = <BucketName>;
private String objectKey = <ObjectKey>;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
try {
BosClientConfiguration config = new BosClientConfiguration();
config.setCredentials(new DefaultBceCredentials(<AccessKeyID>, <SecretAccessKey>));
config.setEndpoint(<EndPoint>);
BosClient client = new BosClient(config);
// 获取数据流
InputStream inputStream = new FileInputStream("/path/to/test.zip");
// 创建ObjectMetadata类的实例
ObjectMetadata meta = new ObjectMetadata();
// 设置ContentLength大小
meta.setContentLength(1000);
// 设置ContentType
meta.setContentType("application/json");
PutObjectResponse putObjectResponseFromInputStream = client.putObject(bucketName, objectKey, inputStream, meta);
// 打印ETag
System.out.println(putObjectResponseFromInputStream.getETag());
} catch (BceServiceException e) {
System.out.println("Error ErrorCode: " + e.getErrorCode());
System.out.println("Error RequestId: " + e.getRequestId());
System.out.println("Error StatusCode: " + e.getStatusCode());
System.out.println("Error Message: " + e.getMessage());
System.out.println("Error ErrorType: " + e.getErrorType());
} catch (BceClientException e) {
System.out.println("Error Message: " + e.getMessage());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}}
用户自定义元数据
BOS支持用户自定义元数据来对Object进行描述。
基本流程
- 创建ObjectMetadata类的实例。
- 执行addUserMetadata()方法对Http Header进行自定义元数据。
- 将设定后的meta作为参数加入client.putObject()中。
示例代码
// 设置自定义元数据name的值为my-data
meta.addUserMetadata("name", "my-data");
// 上传Object
client.putObject(<BucketName>, <ObjectKey>, <Content>, meta);
说明:在上面代码中,用户自定义了一个名字为”name”,值为”my-data”的元数据。当用户下载此Object的时候,此元数据也可以一并得到。一个Object可以有多个类似的参数,但所有的User Meta总大小不能超过2KB。
完整示例
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import android.app.Activity;
import android.os.Bundle;
import com.baidubce.BceClientException;
import com.baidubce.BceServiceException;
import com.baidubce.auth.DefaultBceCredentials;
import com.baidubce.demo.R;
import com.baidubce.services.bos.BosClient;
import com.baidubce.services.bos.BosClientConfiguration;
import com.baidubce.services.bos.model.ObjectMetadata;
import com.baidubce.services.bos.model.PutObjectResponse;
public class ExampleActivity extends Activity {
private String bucketName = <BucketName>;
private String objectKey = <ObjectKey>;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
try {
BosClientConfiguration config = new BosClientConfiguration();
config.setCredentials(new DefaultBceCredentials(<AccessKeyID>, <SecretAccessKey>));
config.setEndpoint(<EndPoint>);
BosClient client = new BosClient(config);
// 获取数据流
InputStream inputStream = new FileInputStream("/path/to/test.zip");
// 创建ObjectMetadata类的实例
ObjectMetadata meta = new ObjectMetadata();
// 自定义元数据
meta.addUserMetadata("name", "my-data");
PutObjectResponse putObjectResponseFromInputStream = client.putObject(<BucketName>, <ObjectKey>, inputStream, meta);
// 打印ETag
System.out.println(putObjectResponseFromInputStream.getETag());
} catch (BceServiceException e) {
System.out.println("Error ErrorCode: " + e.getErrorCode());
System.out.println("Error RequestId: " + e.getRequestId());
System.out.println("Error StatusCode: " + e.getStatusCode());
System.out.println("Error Message: " + e.getMessage());
System.out.println("Error ErrorType: " + e.getErrorType());
} catch (BceClientException e) {
System.out.println("Error Message: " + e.getMessage());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}}
Append方式上传Object
BOS支持AppendObject,即以追加写的方式上传文件,适用场景如日志追加及直播等实时视频文件上传。通过AppendObject操作创建的Object类型为Appendable Object,可以对该Object追加数据;而通过PutObject上传的Object是Normal Object,不可进行数据追加写。AppendObject大小限制为0~5G。
示例代码
public void AppendObject(BosClient client, String bucketName, String objectKey, byte[] byte1, String string1) {
// 获取指定文件
File file = new File("/path/to/file.zip");
// 获取数据流
InputStream inputStream = new FileInputStream("/path/to/test.zip");
// 以文件形式上传Object
AppendObjectResponse appendObjectFromFileResponse = client.appendObject(bucketName, objectKey, file);
// 以数据流形式上传Object
AppendObjectResponse appendObjectResponseFromInputStream = client.appendObject(bucketName, objectKey, inputStream);
// 以二进制串上传Object
AppendObjectResponse appendObjectResponseFromByte = client.appendObject(bucketName, objectKey, byte1);
// 以字符串上传Object
AppendObjectResponse appendObjectResponseFromString = client.appendObject(bucketName, objectKey, string1);
// 向AppendFile追加内容
Long nextOffset = appendObjectFromFileResponse.getNextAppendOffset();
AppendObjectRequest request =new AppendObjectRequest(bucketName, objectKey,
RestartableInputStream.wrap(string1.getBytes()));
request.withOffset(nextOffset);
AppendObjectResponse appendResponse = client.appendObject(request);
}
获取上传进度
Android SDK支持在上传过程中实时提供上传进度信息。目前支持PutObject, AppendObject, UploadPart以及PutSuperObjectFromFile四个接口。进度上传接口的使用必须构造对应的Request (PutObjectRequest
, AppendObjectRequest
, UploadPartRequest
以及PutSuperObjectRequest
)。
SDK提供的上传进度回调接口如下,您可以在其中定义上传过程中您所需要的操作,如更新界面等等。
public interface BceProgressCallback<T extends AbstractBceRequest> {
// request为上传的请求
// currentSize为当前上传的大小(单位:byte)
// totalSize为本次请求需要上传的总大小(单位:byte)
void onProgress(T request, long currentSize, long totalSize);
}
PutObject示例代码
PutObjectRequest request = new PutObjectRequest(this.bucketName, "test", file);
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType("text/plain");
request.setObjectMetadata(objectMetadata);
request.setProgressCallback(new BosProgressCallback<PutObjectRequest>() {
@Override
public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
Log.e(currentSize + "", totalSize + "");
}
});
String eTag = this.client.putObject(request).getETag();
AppendObject示例代码
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType("text/plain");
AppendObjectRequest request = new AppendObjectRequest(this.bucketName, "test", file);
request.setObjectMetadata(objectMetadata);
AppendObjectResponse response = this.client.appendObject(request);
Long nextOffset = response.getNextAppendOffset();
request.withOffset(nextOffset);
request.setProgressCallback(new BosProgressCallback<AppendObjectRequest>() {
@Override
public void onProgress(AppendObjectRequest request, long currentSize, long totalSize) {
Log.e(currentSize + "", totalSize + "");
}
});
response = this.client.appendObject(request);
UploadPart示例代码
UploadPartRequest request = new UploadPartRequest().withBucketName(this.bucketName)
.withKey("test").withUploadId(uploadId).withPartNumber(1).withPartSize(8000)
.withInputStream(fis);
request.setProgressCallback(new BosProgressCallback<UploadPartRequest>() {
@Override
public void onProgress(UploadPartRequest request, long currentSize, long totalSize) {
Log.e(currentSize + "", totalSize + "");
}
});
UploadPartResponse response = this.client.uploadPart(request);
PutSuperObjectFromFile示例代码
PutSuperObjectRequest request = new PutSuperObjectRequest().withBucketName(this.bucketName)
.withKey("test").withPartSize(1024*1024*2L).withFile(file);
request.setProgressCallback(new BosProgressCallback<PutSuperObjectRequest>() {
@Override
public void onProgress(PutSuperObjectRequest request, long currentSize, long totalSize) {
Log.e(currentSize + "", totalSize + "");
}
});
PutSuperObjectResponse response = this.client.putSuperObjectFromFile(request);
目前,SDK默认上传进度的回调粒度为2048个字节。您可以通过如下方法设置一个更适合您App应用的回调粒度:
BosClientConfiguration config=new BosClientConfiguration(); config.setUploadSegmentPart(1024);
注意: 该值必须在1-8192之间,如不在该范围内,Android SDK会强制设置为2048.
取消接口
Android SDK支持在请求过程中取消本次请求,其中上传请求中剩余的数据将不再会上传至BOS,下载请求中取消操作会关闭连接,执行中的操作会抛出Request is canceled!
异常
所有的BOS操作都可以使用取消接口,但是已经完成的请求无法被取消,已经完成的操作也不会抛出异常
// 以上传接口取消为例
final PutObjectRequest req = new PutObjectRequest(<BucketName>, <ObjectName>,
new FileInputStream(<FilePath>));
Runnable cancelTask = new Runnable() {
@Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace()
}
// 取消本次上传请求
req.cancel();
}
};
new Thread(cancelTask).start();
client.putObject(req);
同步回调
Android SDK支持BOS服务端同步回调接口,通过在PutObjectRequest中,设置process参数,就可以在上传完成后,让BOS服务端主动调用回调接口来达到通知客户目的。
PutObjectRequest request = new PutObjectRequest({bucket}, {object}, {inputStream});
// 设置x-bce-process参数
request.setProcess({x-bce-process});
PutObjectResponse response = client.putObject(request);
// 获取返回的http status code
int statusCode = response.getHttpResponse().getStatusCode();
// 获取返回的回调接口返回的数据
string callbackString = response.getServerCallbackReturnBody();
单链接限速
对象存储BOS的单Bucket带宽是有限制的,当用户的上传或下载占用带宽达到带宽限制阈值时,会返回RequestRateLimitExceeded的错误码。
为保证用户能够正常使用服务,BOS支持在进行上传、下载等行为时进行流量控制,保证大流量服务占用带宽不会对其他应用服务造成影响。
读写接口支持设置指定限速值,限速值的取值范围为819200~838860800,单位为bit/s,即100KB/s~100MB/s。限速值取值必须为数字,BOS将按照指定的限速值对此次请求进行限速,当限速值不在此范围或不合法时将返回400错误码。
当前PutObjectRequest、PutSuperObjectRequest、UploadPartRequest、CopyObjectRequest、GetObjectRequest均支持设置单链接限速。 以PutObjectRequest为例:
PutObjectRequest request = new PutObjectRequest({bucket}, {object}, {inputStream});
// 设置单链接限速
request.setTrafficLimitBitPS(819200);