OSS提供基于MD5和CRC64的数据校验,确保上传、下载和拷贝文件(Object)过程中的数据完整性。
MD5校验
如果上传文件时设置了Content-MD5,OSS会根据接收的内容计算MD5。OSS计算的MD5值和上传提供的MD5值不一致时,则返回InvalidDigest异常,从而保证数据的完整性。返回InvalidDigest异常后,您需要重新上传文件。
以下代码用于上传文件时进行MD5校验:
// Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。 String accessKeyId = "<yourAccessKeyId>"; String accessKeySecret = "<yourAccessKeySecret>"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 上传字符串。 String content = "Hello OSS"; ObjectMetadata meta = new ObjectMetadata(); // 设置MD5校验。 String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(content.getBytes())); meta.setContentMD5(md5); ossClient.putObject("<yourBucketName>", "<yourObjectName>", new ByteArrayInputStream(content.getBytes()), meta); // 关闭OSSClient。 ossClient.shutdown();
说明 putObject、getObject、appendObject、postObject、uploadPart支持MD5校验。
CRC64校验
上传、下载和拷贝文件时默认开启CRC数据校验,确保数据的完整性。
说明
- putObject、getObject、appendObject、uploadPart支持CRC64校验。上传时默认开启CRC校验,如果客户端计算的CRC值与服务端返回的CRC值不一致, 则会抛出InconsistentException异常。
- 范围下载不支持CRC64校验。
- CRC64校验会占用一定的CPU,对上传、下载速度均会有影响。
- 下载文件时CRC64校验
以下代码用于下载文件时进行CRC64数据完整性校验:
// Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。 String accessKeyId = "<yourAccessKeyId>"; String accessKeySecret = "<yourAccessKeySecret>"; String bucketName = "<yourBucketName>"; String objectName = "<yourObjectName>"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 流式下载。 GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectName); OSSObject ossObject = ossClient.getObject(bucketName, objectName); // 读取文件内容,只有读取文件内容之后才能获取clientCrc。 System.out.println("Object content:"); BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent())); while (true) { String line = reader.readLine(); if (line == null) break; System.out.println("\n" + line); } // 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。 reader.close(); // 查看客户端是否开启了crc校验,默认是开启状态。 Boolean isCrcCheckEnabled = ((OSSClient)ossClient).getClientConfiguration().isCrcCheckEnabled(); // 查看是否是范围下载请求。范围下载方式不支持校验crc。 Boolean isRangGetRequest = getObjectRequest.getHeaders().get(OSSHeaders.RANGE) != null; // 校验crc,只有读取文件内容之后才能获取clientCrc。 if (isCrcCheckEnabled && !isRangGetRequest) { Long clientCRC = IOUtils.getCRCValue(ossObject.getObjectContent()); OSSUtils.checkChecksum(clientCRC, ossObject.getServerCRC(), ossObject.getRequestId()); } // 关闭OSSClient。 ossClient.shutdown();
- 追加上传时CRC64校验
// Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。 String accessKeyId = "<yourAccessKeyId>"; String accessKeySecret = "<yourAccessKeySecret>"; String bucketName = "<yourBucketName>"; String objectName = "<yourObjectName>"; String firstAppendContent = "<yourFirstAppendContent>"; String secondAppendContent = "<yourSecondAppendContent>"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 第一次追加。 AppendObjectRequest appendObjectRequest = new AppendObjectRequest(bucketName, objectName, new ByteArrayInputStream(firstAppendContent.getBytes())); appendObjectRequest.setPosition(0L); // 初始化crc。初始化crc之后,SDK内部默认会对上传结果进行crc校验。 appendObjectRequest.setInitCRC(0L); AppendObjectResult appendObjectResult = ossClient.appendObject(appendObjectRequest); // 第二次追加。 appendObjectRequest = new AppendObjectRequest(bucketName, objectName, new ByteArrayInputStream(secondAppendContent.getBytes())); appendObjectRequest.setPosition(appendObjectResult.getNextPosition()); // 初始化crc设置为已上传数据的crc。初始化crc之后,SDK内部默认会对上传结果进行crc校验。 appendObjectRequest.setInitCRC(appendObjectResult.getClientCRC()); ossClient.appendObject(appendObjectRequest); // 关闭OSSClient。 ossClient.shutdown();