禁止覆盖同名文件
默认情况下,如果已经存在同名文件(Object)且对该文件有访问权限,则新添加的文件将覆盖原有的文件。本文介绍如何通过设置请求头x-oss-forbid-overwrite在简单上传、拷贝文件及分片上传等场景中禁止覆盖同名文件。
简单上传
以下代码用于简单上传时禁止覆盖同名文件:
// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
String bucketName = "<yourBucketName>";
String objectName = "<yourObjectName>";
String content = "Hello OSS!";
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 创建PutObjectRequest对象。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
// 指定上传文件操作时是否覆盖同名Object。
// 不指定x-oss-forbid-overwrite时,默认覆盖同名Object。
// 指定x-oss-forbid-overwrite为false时,表示允许覆盖同名Object。
// 指定x-oss-forbid-overwrite为true时,表示禁止覆盖同名Object,如果同名Object已存在程序将报错。
metadata.setHeader("x-oss-forbid-overwrite", "true");
putObjectRequest.setMetadata(metadata);
// 上传文件。
ossClient.putObject(putObjectRequest);
// 关闭OSSClient。
ossClient.shutdown();
简单上传的更多详情,请参见PutObject。
拷贝文件
- 通过CopyObjectRequest拷贝
以下代码用于通过CopyObjectRequest拷贝小文件时禁止覆盖同名文件:
// Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。 String accessKeyId = "<yourAccessKeyId>"; String accessKeySecret = "<yourAccessKeySecret>"; String sourceBucketName = "<yourSourceBucketName>"; String sourceObjectName = "<yourSourceObjectName>"; String destinationBucketName = "<yourDestinationBucketName>"; String destinationObjectName = "<yourDestinationObjectName>"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 创建CopyObjectRequest对象。 CopyObjectRequest copyObjectRequest = new CopyObjectRequest(sourceBucketName, sourceObjectName, destinationBucketName, destinationObjectName); // 设置新的文件元信息。 ObjectMetadata meta = new ObjectMetadata(); meta.setContentType("text/html"); // 指定拷贝文件操作时是否覆盖同名Object。 // 不指定x-oss-forbid-overwrite时,默认覆盖同名Object // 指定x-oss-forbid-overwrite为false时,表示允许覆盖同名Object。 // 指定x-oss-forbid-overwrite为true时,表示禁止覆盖同名Object,如果同名Object已存在程序将报错。 metadata.setHeader("x-oss-forbid-overwrite", "true"); copyObjectRequest.setNewObjectMetadata(meta); // 拷贝文件。 CopyObjectResult result = ossClient.copyObject(copyObjectRequest); System.out.println("ETag: " + result.getETag() + " LastModified: " + result.getLastModified()); // 关闭OSSClient。 ossClient.shutdown();
- 拷贝大文件
以下代码用于拷贝大文件(分片拷贝)时禁止覆盖同名文件:
// Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。 String accessKeyId = "<yourAccessKeyId>"; String accessKeySecret = "<yourAccessKeySecret>"; String sourceBucketName = "<yourSourceBucketName>"; String sourceObjectName = "<yourSourceObjectName>"; String destinationBucketName = "<yourDestinationBucketName>"; String destinationObjectName = "<yourDestinationObjectName>"; ObjectMetadata objectMetadata = ossClient.getObjectMetadata(sourceBucketName, sourceObjectName); // 获取被拷贝文件的大小。 long contentLength = objectMetadata.getContentLength(); // 设置分片大小为10MB。 long partSize = 1024 * 1024 * 10; // 计算分片总数。 int partCount = (int) (contentLength / partSize); if (contentLength % partSize != 0) { partCount++; } System.out.println("total part count:" + partCount); // 初始化拷贝任务。可以通过InitiateMultipartUploadRequest指定目标文件元信息。 InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(destinationBucketName, destinationObjectName); // 指定拷贝文件操作时是否覆盖同名Object。 // 不指定x-oss-forbid-overwrite时,默认覆盖同名Object。 // 指定x-oss-forbid-overwrite为false时,表示允许覆盖同名Object。 // 指定x-oss-forbid-overwrite为true时,表示禁止覆盖同名Object,如果同名Object已存在程序将报错。 ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader("x-oss-forbid-overwrite", "true"); initiateMultipartUploadRequest.setObjectMetadata(metadata); InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient.initiateMultipartUpload(initiateMultipartUploadRequest); String uploadId = initiateMultipartUploadResult.getUploadId(); // 分片拷贝。 List<PartETag> partETags = new ArrayList<PartETag>(); for (int i = 0; i < partCount; i++) { // 计算每个分片的大小。 long skipBytes = partSize * i; long size = partSize < contentLength - skipBytes ? partSize : contentLength - skipBytes; // 创建UploadPartCopyRequest。可以通过UploadPartCopyRequest指定限定条件。 UploadPartCopyRequest uploadPartCopyRequest = new UploadPartCopyRequest(sourceBucketName, sourceObjectName, destinationBucketName, destinationObjectName); uploadPartCopyRequest.setUploadId(uploadId); uploadPartCopyRequest.setPartSize(size); uploadPartCopyRequest.setBeginIndex(skipBytes); uploadPartCopyRequest.setPartNumber(i + 1); UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest); // 将返回的分片ETag保存到partETags中。 partETags.add(uploadPartCopyResult.getPartETag()); } // 提交分片拷贝任务。 CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest( destinationBucketName, destinationObjectName, uploadId, partETags); // 指定拷贝文件操作时是否覆盖同名Object。 // 不指定x-oss-forbid-overwrite时,默认覆盖同名Object // 指定x-oss-forbid-overwrite为false时,表示允许覆盖同名Object。 // 指定x-oss-forbid-overwrite为true时,表示禁止覆盖同名Object,如果同名Object已存在程序将报错。 completeMultipartUploadRequest.addHeader("x-oss-forbid-overwrite", "true"); ossClient.completeMultipartUpload(completeMultipartUploadRequest); // 关闭OSSClient。 ossClient.shutdown();
拷贝文件的更多详情,请参见CopyObject。
分片上传
以下代码用于分片上传时禁止覆盖同名文件:
// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
String bucketName = "<yourBucketName>";
String objectName = "<yourObjectName>";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 创建InitiateMultipartUploadRequest对象。
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
// 指定分片上传操作时是否覆盖同名Object。
// 不指定x-oss-forbid-overwrite时,默认覆盖同名Object。
// 指定x-oss-forbid-overwrite为false时,表示允许覆盖同名Object。
// 指定x-oss-forbid-overwrite为true时,表示禁止覆盖同名Object,如果同名Object已存在程序将报错。
metadata.setHeader("x-oss-forbid-overwrite", "true");
request.setObjectMetadata(metadata);
// 初始化分片。
InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
// 返回uploadId,它是分片上传事件的唯一标识,您可以根据这个ID来发起相关的操作,如取消分片上传、查询分片上传等。
String uploadId = upresult.getUploadId();
// partETags是PartETag的集合。PartETag由分片的ETag和分片号组成。
List<PartETag> partETags = new ArrayList<PartETag>();
// 计算文件有多少个分片。
final long partSize = 1 * 1024 * 1024L; // 1MB
final File sampleFile = new File("<localFile>");
long fileLength = sampleFile.length();
int partCount = (int) (fileLength / partSize);
if (fileLength % partSize != 0) {
partCount++;
}
// 遍历分片上传。
for (int i = 0; i < partCount; i++) {
long startPos = i * partSize;
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
InputStream instream = new FileInputStream(sampleFile);
// 跳过已经上传的分片。
instream.skip(startPos);
UploadPartRequest uploadPartRequest = new UploadPartRequest();
uploadPartRequest.setBucketName(bucketName);
uploadPartRequest.setKey(objectName);
uploadPartRequest.setUploadId(uploadId);
uploadPartRequest.setInputStream(instream);
// 设置分片大小。除了最后一个分片没有大小限制,其他的分片最小为100KB。
uploadPartRequest.setPartSize(curPartSize);
// 设置分片号。每一个上传的分片都有一个分片号,取值范围是1~10000,如果超出这个范围,OSS将返回InvalidArgument的错误码。
uploadPartRequest.setPartNumber( i + 1);
// 每个分片不需要按顺序上传,甚至可以在不同客户端上传,OSS会按照分片号排序组成完整的文件。
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
// 每次上传分片之后,OSS的返回结果会包含一个PartETag。PartETag将被保存到partETags中。
partETags.add(uploadPartResult.getPartETag());
}
// 创建CompleteMultipartUploadRequest对象。
// 在执行完成分片上传操作时,需要提供所有有效的partETags。OSS收到提交的partETags后,会逐一验证每个分片的有效性。当所有的数据分片验证通过后,OSS将把这些分片组合成一个完整的文件。
CompleteMultipartUploadRequest completeMultipartUploadRequest =
new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
// 指定分片上传操作时是否覆盖同名Object。
// 不指定x-oss-forbid-overwrite时,默认覆盖同名Object。
// 指定x-oss-forbid-overwrite为false时,表示允许覆盖同名Object。
// 指定x-oss-forbid-overwrite为true时,表示禁止覆盖同名Object,如果同名Object已存在程序将报错。
completeMultipartUploadRequest.addHeader("x-oss-forbid-overwrite", "true");
// 完成上传。
CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
// 关闭OSSClient。
ossClient.shutdown();
分片上传的更多详情,请参见InitiateMultipartUpload以及CompleteMultipartUpload。
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。
评论