本文介绍如何下载文件。

简单下载

下载指定文件,下载后将获得文件的输入流,此操作要求用户对该Object有读权限。 同步调用:

//构造下载文件请求
GetObjectRequest get = new GetObjectRequest("<bucketName>", "<objectKey>");

//设置下载进度回调
get.setProgressListener(new OSSProgressCallback<GetObjectRequest>() {
            @Override
            public void onProgress(GetObjectRequest request, long currentSize, long totalSize) {
                OSSLog.logDebug("getobj_progress: " + currentSize+"  total_size: " + totalSize, false);
            }
        });

try {
	// 同步执行下载请求,返回结果
	GetObjectResult getResult = oss.getObject(get);

	Log.d("Content-Length", "" + getResult.getContentLength());

	// 获取文件输入流
	InputStream inputStream = getResult.getObjectContent();

	byte[] buffer = new byte[2048];
	int len;

	while ((len = inputStream.read(buffer)) != -1) {
		// 处理下载的数据,比如图片展示或者写入文件等
	}

	// 下载后可以查看文件元信息
	ObjectMetadata metadata = getResult.getMetadata();
	Log.d("ContentType", metadata.getContentType());


} catch (ClientException e) {
	// 本地异常如网络异常等
	e.printStackTrace();
} catch (ServiceException e) {
	// 服务异常
	Log.e("RequestId", e.getRequestId());
	Log.e("ErrorCode", e.getErrorCode());
	Log.e("HostId", e.getHostId());
	Log.e("RawMessage", e.getRawMessage());
} catch (IOException e) {
	e.printStackTrace();
}

异步调用:

GetObjectRequest get = new GetObjectRequest("<bucketName>", "<objectKey>");
//设置下载进度回调
get.setProgressListener(new OSSProgressCallback<GetObjectRequest>() {
            @Override
            public void onProgress(GetObjectRequest request, long currentSize, long totalSize) {
                OSSLog.logDebug("getobj_progress: " + currentSize+"  total_size: " + totalSize, false);
            }
        });
OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
	@Override
	public void onSuccess(GetObjectRequest request, GetObjectResult result) {
		// 请求成功
		InputStream inputStream = result.getObjectContent();

		byte[] buffer = new byte[2048];
		int len;

		try {
			while ((len = inputStream.read(buffer)) != -1) {
				// 处理下载的数据
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onFailure(GetObjectRequest 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());
		}
	}
});

图片处理

OSS图片处理是OSS对外提供的海量、安全、低成本、高可靠的图片处理服务。 用户将原始图片上传保存到OSS,通过简单的 RESTful 接口,在任何时间、任何地点、任何互联网设备上对图片进行处理。 图片处理提供图片处理接口,图片上传请使用上传接口。基于OSS图片处理,用户可以搭建自己的图片处理服务。

图片处理的详细信息请参见OSS图片处理指南

OSS图片处理提供以下功能:

SDK中使用时,只需要在下载图片时,调用request.setxOssProcess()方法设置处理参数。示例:

// 构造图片下载请求
GetObjectRequest get = new GetObjectRequest("<bucketName>", "example.jpg");

// 图片处理
request.setxOssProcess("image/resize,m_fixed,w_100,h_100");

OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
    @Override
    public void onSuccess(GetObjectRequest request, GetObjectResult result) {
        // 请求成功
        InputStream inputStream = result.getObjectContent();

        byte[] buffer = new byte[2048];
        int len;

        try {
            while ((len = inputStream.read(buffer)) != -1) {
                // 处理下载的数据
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onFailure(GetObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
        // 处理异常
    }
});

需要对图片进行其它处理,只要替换request.setxOssProcess()的参数就可以了。需要帮助,请参考:

  • 可视化图片处理工具 ImageStyleViever ,可以直观的看到OSS图片处理的结果
  • OSS图片处理的功能、使用演示 页面

指定范围下载

您可以在下载文件时指定一段范围,对于较大的Object适于使用此功能;如果在请求头中使用Range参数,则返回消息中会包含整个文件的长度和此次返回的范围。 如:

GetObjectRequest get = new GetObjectRequest("<bucketName>", "<objectKey>");

// 设置范围
get.setRange(new Range(0, 99)); // 下载0到99字节共100个字节,文件范围从0开始计算
// get.setRange(new Range(100, Range.INFINITE)); // 下载从100个字节到结尾

OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
	@Override
	public void onSuccess(GetObjectRequest request, GetObjectResult result) {
		// 请求成功
		InputStream inputStream = result.getObjectContent();

		byte[] buffer = new byte[2048];
		int len;

		try {
			while ((len = inputStream.read(buffer)) != -1) {
				// 处理下载的数据
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onFailure(GetObjectRequest 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());
		}
	}
});

只获取文件元信息

通过headObject方法可以只获文件元信息而不获取文件的实体。代码如下:

// 创建同步获取文件元信息请求
HeadObjectRequest head = new HeadObjectRequest("<bucketName>", "<objectKey>");

OSSAsyncTask task = oss.asyncHeadObject(head, new OSSCompletedCallback<HeadObjectRequest, HeadObjectResult>() {
	@Override
	public void onSuccess(HeadObjectRequest request, HeadObjectResult result) {
		Log.d("headObject", "object Size: " + result.getMetadata().getContentLength());
		Log.d("headObject", "object Content Type: " + result.getMetadata().getContentType());
	}

	@Override
	public void onFailure(HeadObjectRequest 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.waitUntilFinished();

数据完整性校验

因为移动端网络环境的复杂性,数据在客户端和服务器之间传输时有可能会出错。因此OSS SDK提供了基于CRC的端到端的数据完整性效验。

CRC校验 在读取下载数据流的时候,如果开启了crc效验,会在数据流读取完毕后自动验证数据完整性。

GetObjectRequest request = new GetObjectRequest(OSSTestConfig.ANDROID_TEST_BUCKET, testFile);
//开启CRC效验
request.setCRC64(OSSRequest.CRC64Config.YES);
//....
try{
	GetObjectResult result = oss.getObject(request);
	InputStream in = result.getObjectContent();
	ByteArrayOutputStream output = new ByteArrayOutputStream();
    byte[] buffer = new byte[BUFFER_SIZE];
    int len;
    while ((len = in.read(buffer)) > -1) {
            output.write(buffer, 0, len);
    }
    output.flush();
	in.close();
}catch(ClientException e){
	//...
}catch(InconsistentException e){
    //....
}