If you need only a part of a file, you can perform a range download to retrieve a specific range of data.
Precautions
In this topic, the public endpoint of the China (Hangzhou) region is used. To access OSS from other Alibaba Cloud services in the same region, use an internal endpoint. For details about supported regions and endpoints, see OSS regions and endpoints.
In this topic, access credentials are obtained from environment variables. For more information about how to configure access credentials, see Configure access credentials.
In this topic, an OSSClient instance is created by using an OSS endpoint. If you want to create an OSSClient instance by using custom domain names or Security Token Service (STS), see Configuration examples for common scenarios.
To perform a range download, you must have the
oss:GetObjectpermission. For more information, see Grant custom permissions to a RAM user.
Specify a normal download range
The following code shows how to specify a valid download range to download a file.
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import java.io.InputStream;
public class Demo {
public static void main(String[] args) throws Exception {
// The China (Hangzhou) endpoint is used as an example. Specify the actual endpoint.
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Obtain access credentials from environment variables. Before you run this sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Specify the bucket name. Example: examplebucket.
String bucketName = "examplebucket";
// Specify the full path of the object. Example: exampledir/exampleobject.txt. The full path cannot include the bucket name.
String objectName = "exampledir/exampleobject.txt";
// Specify the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the region to cn-hangzhou.
String region = "cn-hangzhou";
// Create an OSSClient instance.
// When the OSSClient instance is no longer in use, call the shutdown method to release resources.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
InputStream in = null;
try {
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectName);
// For a file of 1,000 bytes, the normal byte range is 0 to 999.
// Get the data within the range of 0 to 999 bytes, which includes byte 0 and byte 999, for a total of 1,000 bytes. If the specified range is invalid, for example, the start or end position is a negative value or is greater than the file size, the entire file is downloaded.
getObjectRequest.setRange(0, 999);
// Perform a range download.
OSSObject ossObject = ossClient.getObject(getObjectRequest);
// Read the data.
byte[] buf = new byte[1024];
in = ossObject.getObjectContent();
for (int n = 0; n != -1; ) {
n = in.read(buf, 0, buf.length);
}
ossObject.close();
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
// After the data is read, you must close the stream. Otherwise, connection leaks may occur. This can exhaust available connections and cause the program to stop working.
if (in != null) {
in.close();
}
}
}
} A single stream read may not retrieve all the data. To read 64 KB of data from a stream, you must read the stream multiple times until 64 KB of data is read or the end of the file is reached. For more information, see InputStream.read.
byte[] buf = new byte[1024];
InputStream in = ossObject.getObjectContent();
for (int n = 0; n != -1; ) {
n = in.read(buf, 0, buf.length);
}
in.close();Specify an invalid download range
Assume that you have an object that is 1,000 bytes in size. The valid download range is 0 to 999. If you specify a range outside this valid interval, the Range header has no effect. OSS returns a 200 status code and sends the entire object. The following examples show invalid requests and their responses:
If you specify Range: bytes=500-2000, the end of the range is outside the valid interval. OSS returns the entire object and an HTTP status code of 200.
If you specify Range: bytes=1000-2000, the start of the range is outside the valid interval. OSS returns the entire object and an HTTP status code of 200.
Standard behavior for range download
You can add the x-oss-range-behavior: standard header to the request to change the OSS download behavior for ranges that are outside the valid interval. Assume that you have an object that is 1,000 bytes in size:
If you specify Range: bytes=500-2000, the end of the range is outside the valid interval. OSS returns the content from byte 500 to byte 999 and an HTTP status code of 206.
If you specify Range: bytes=1000-2000, the start of the range is outside the valid interval. OSS returns an HTTP status code of 416 and the InvalidRange error code.
The following code shows how to perform a range download with standard behavior.
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
public class Demo {
public static void main(String[] args) throws Exception {
// The China (Hangzhou) endpoint is used as an example. Specify the actual endpoint.
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Obtain access credentials from environment variables. Before you run this sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Specify the bucket name. Example: examplebucket.
String bucketName = "examplebucket";
// Specify the full path of the object. Example: exampledir/exampleobject.txt. The full path cannot include the bucket name.
String objectName = "exampledir/exampleobject.txt";
// Specify the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the region to cn-hangzhou.
String region = "cn-hangzhou";
// Create an OSSClient instance.
// When the OSSClient instance is no longer in use, call the shutdown method to release resources.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Explicitly declare the use of the V4 signature algorithm.
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.region(region)
.build();
try {
// The end of the range is outside the valid interval. OSS returns the content from byte 500 to byte 999 and an HTTP status code of 206.
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectName);
getObjectRequest.setRange(500, 2000);
getObjectRequest.addHeader("x-oss-range-behavior", "standard");
OSSObject ossObject = ossClient.getObject(getObjectRequest);
ossObject.close();
System.out.println("standard get " + "500~2000 "+ "statusCode:" + ossObject.getResponse().getStatusCode());
System.out.println("standard get " + "500~2000 " + "contentLength:" + ossObject.getResponse().getContentLength());
// The start of the range is outside the valid interval. The following code throws an exception. OSS returns an HTTP status code of 416 and the InvalidRange error code.
getObjectRequest = new GetObjectRequest(bucketName, objectName);
getObjectRequest.setRange(1000, 2000);
getObjectRequest.addHeader("x-oss-range-behavior", "standard");
OSSObject ossObject2 = ossClient.getObject(getObjectRequest);
ossObject2.close();
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}References
For more information about the API operation for range download, see GetObject.