SDK 支持将本地大文件通过 uploadFile 断点续传接口上传。uploadFile 上传过程中,会在本地记录 checkpoint 文件。如果出现网络异常或程序崩溃等情况导致文件上传失败,再次调用该接口,可以从 checkpoint 文件记录的进度恢复并继续上传。
以下代码展示如何使用断点续传接口上传文件。
import android.os.Bundle; import android.util.Log; import androidx.appcompat.app.AppCompatActivity; import com.volcengine.tos.TOSV2; import com.volcengine.tos.TOSV2ClientBuilder; import com.volcengine.tos.TosException; import com.volcengine.tos.model.object.CreateMultipartUploadInput; import com.volcengine.tos.model.object.UploadFileV2Input; import com.volcengine.tos.model.object.UploadFileV2Output; public class UploadFileExample extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { String endpoint = "your endpoint"; String region = "your region"; String accessKey = "your access key"; String secretKey = "your secret key"; String securityToken = "your security token"; String bucketName = "your bucket name"; String objectKey = "your object key"; // uploadFilePath 设置待上传的文件路径,建议使用绝对路径,确保文件存在,不支持上传文件夹 String uploadFilePath = "the path of file to upload"; // taskNum 设置并发上传的并发数,范围为 1-1000 int taskNum = 5; // partSize 设置文件分片大小,范围为 5MB - 5GB,默认为 20MB long partSize = 10 * 1024 * 1024; // enableCheckpoint 设置是否开启断点续传功能,开启则会在本地记录上传进度 boolean enableCheckpoint = true; // checkpointFilePath 设置断点续传记录文件存放位置,若不设置则默认在 uploadFilePath 路径下生成 // 其格式为 {uploadFilePath}.{bucket+objectKey 的 Base64Md5 值}.upload String checkpointFilePath = "the checkpoint file path"; super.onCreate(savedInstanceState); setContentView(R.layout.activity_display_message); TOSV2 tos = new TOSV2ClientBuilder().build(region, endpoint, accessKey, secretKey, securityToken); Thread tosThread = new Thread(new Runnable() { @Override public void run() { try{ CreateMultipartUploadInput create = new CreateMultipartUploadInput().setBucket(bucketName).setKey(objectKey); UploadFileV2Input input = new UploadFileV2Input().setCreateMultipartUploadInput(create) .setFilePath(uploadFilePath).setEnableCheckpoint(enableCheckpoint) .setCheckpointFile(checkpointFilePath).setPartSize(partSize).setTaskNum(taskNum); UploadFileV2Output output = tos.uploadFile(input); Log.i("uploadFile", "uploadFile succeed, object's etag is " + output.getEtag()); Log.i("uploadFile", "uploadFile succeed, object's crc64 is " + output.getHashCrc64ecma()); } catch (TosException e) { Log.e("TosException","uploadFile failed"); e.printStackTrace(); } } }); tosThread.start(); } }
uploadFile 接口调用过程会发送初始化分片、上传分片、合并分片等事件,您可以传入自定义接口来监听上传的相关事件,并实现自定义的业务逻辑。
以下代码展示如何使用事件监听功能。
import android.os.Bundle; import android.util.Log; import androidx.appcompat.app.AppCompatActivity; import com.volcengine.tos.TOSV2; import com.volcengine.tos.TOSV2ClientBuilder; import com.volcengine.tos.TosException; import com.volcengine.tos.comm.event.UploadEventType; import com.volcengine.tos.model.object.CreateMultipartUploadInput; import com.volcengine.tos.model.object.UploadEvent; import com.volcengine.tos.model.object.UploadEventListener; import com.volcengine.tos.model.object.UploadFileV2Input; import com.volcengine.tos.model.object.UploadFileV2Output; public class UploadFileWithEventListenerExample extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { String endpoint = "your endpoint"; String region = "your region"; String accessKey = "your access key"; String secretKey = "your secret key"; String securityToken = "your security token"; String bucketName = "your bucket name"; String objectKey = "your object key"; // uploadFilePath 设置待上传的文件路径,建议使用绝对路径,确保文件存在,不支持上传文件夹 String uploadFilePath = "the path of file to upload"; // taskNum 设置并发上传的并发数,范围为 1-1000 int taskNum = 5; // partSize 设置文件分片大小,范围为 5MB - 5GB,默认为 20MB long partSize = 10 * 1024 * 1024; // enableCheckpoint 设置是否开启断点续传功能,开启则会在本地记录上传进度 boolean enableCheckpoint = true; // checkpointFilePath 设置断点续传记录文件存放位置,若不设置则默认在 uploadFilePath 路径下生成 // 其格式为 {uploadFilePath}.{bucket+objectKey 的 Base64Md5 值}.upload String checkpointFilePath = "the checkpoint file path"; super.onCreate(savedInstanceState); setContentView(R.layout.activity_display_message); TOSV2 tos = new TOSV2ClientBuilder().build(region, endpoint, accessKey, secretKey, securityToken); Thread tosThread = new Thread(new Runnable() { @Override public void run() { try{ CreateMultipartUploadInput create = new CreateMultipartUploadInput().setBucket(bucketName).setKey(objectKey); UploadEventListener listener = new UploadEventListener() { @Override public void eventChange(UploadEvent uploadEvent) { if (uploadEvent.getUploadEventType() == UploadEventType.UploadEventCreateMultipartUploadSucceed) { Log.i("uploadFile", "event change, createMultipartUpload succeed"); } if (uploadEvent.getUploadEventType() == UploadEventType.UploadEventCreateMultipartUploadFailed) { Log.i("uploadFile", "event change, createMultipartUpload failed"); } if (uploadEvent.getUploadEventType() == UploadEventType.UploadEventUploadPartSucceed) { Log.i("uploadFile", "event change, uploadPart succeed"); } if (uploadEvent.getUploadEventType() == UploadEventType.UploadEventUploadPartFailed) { Log.i("uploadFile", "event change, uploadPart failed"); } if (uploadEvent.getUploadEventType() == UploadEventType.UploadEventUploadPartAborted) { Log.i("uploadFile", "event change, uploadPart aborted"); } if (uploadEvent.getUploadEventType() == UploadEventType.UploadEventCompleteMultipartUploadSucceed) { Log.i("uploadFile", "event change, completeMultipartUpload succeed"); } if (uploadEvent.getUploadEventType() == UploadEventType.UploadEventCompleteMultipartUploadFailed) { Log.i("uploadFile", "event change, completeMultipartUpload failed"); } } }; UploadFileV2Input input = new UploadFileV2Input().setCreateMultipartUploadInput(create) .setFilePath(uploadFilePath).setEnableCheckpoint(enableCheckpoint) .setCheckpointFile(checkpointFilePath).setPartSize(partSize).setTaskNum(taskNum) .setUploadEventListener(listener); UploadFileV2Output output = tos.uploadFile(input); Log.i("uploadFile", "uploadFile succeed, object's etag is " + output.getEtag()); Log.i("uploadFile", "uploadFile succeed, object's crc64 is " + output.getHashCrc64ecma()); } catch (TosException e) { Log.e("TosException","uploadFile failed"); e.printStackTrace(); } } }); tosThread.start(); } }
uploadFile 接口支持您主动暂停或取消断点续传任务。暂停断点续传任务会停止上传,再次调用 uploadFile 时可以从上次暂停的位置继续上传。取消断点续传任务会停止上传,删除本地的 checkpoint 文件,并调用 abortMultipartUpload 来删除分片上传任务,再次调用 uploadFile 时会重新开始上传。
以下代码展示如何暂停或取消断点续传。
import android.os.Bundle; import android.util.Log; import androidx.appcompat.app.AppCompatActivity; import com.volcengine.tos.TOSV2; import com.volcengine.tos.TOSV2ClientBuilder; import com.volcengine.tos.TosException; import com.volcengine.tos.comm.event.UploadEventType; import com.volcengine.tos.model.object.CreateMultipartUploadInput; import com.volcengine.tos.model.object.UploadEvent; import com.volcengine.tos.model.object.UploadEventListener; import com.volcengine.tos.model.object.UploadFileV2Input; import com.volcengine.tos.model.object.UploadFileV2Output; public class UploadFileWithCancelExample extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { String endpoint = "your endpoint"; String region = "your region"; String accessKey = "your access key"; String secretKey = "your secret key"; String securityToken = "your security token"; String bucketName = "your bucket name"; String objectKey = "your object key"; // uploadFilePath 设置待上传的文件路径,建议使用绝对路径,确保文件存在,不支持上传文件夹 String uploadFilePath = "the path of file to upload"; // taskNum 设置并发上传的并发数,范围为 1-1000 int taskNum = 5; // partSize 设置文件分片大小,范围为 5MB - 5GB,默认为 20MB long partSize = 10 * 1024 * 1024; // enableCheckpoint 设置是否开启断点续传功能,开启则会在本地记录上传进度 boolean enableCheckpoint = true; // checkpointFilePath 设置断点续传记录文件存放位置,若不设置则默认在 uploadFilePath 路径下生成 // 其格式为 {uploadFilePath}.{bucket+objectKey 的 Base64Md5 值}.upload String checkpointFilePath = "the checkpoint file path"; super.onCreate(savedInstanceState); setContentView(R.layout.activity_display_message); TOSV2 tos = new TOSV2ClientBuilder().build(region, endpoint, accessKey, secretKey, securityToken); Thread tosThread = new Thread(new Runnable() { @Override public void run() { try{ CreateMultipartUploadInput create = new CreateMultipartUploadInput().setBucket(bucketName).setKey(objectKey); UploadFileV2Input input = new UploadFileV2Input().setCreateMultipartUploadInput(create) .setFilePath(uploadFilePath).setEnableCheckpoint(enableCheckpoint) .setCheckpointFile(checkpointFilePath).setPartSize(partSize).setTaskNum(taskNum); // 以下代码通过 UploadEventListener 监听上传事件。 // 如果出现 UploadEventUploadPartFailed 事件,即有上传失败的分片时就终止上传任务。 // 以下代码仅作为示例,用户可根据业务需要进行使用。 boolean isAbort = true; UploadEventListener listener = new UploadEventListener() { @Override public void eventChange(UploadEvent uploadEvent) { if (uploadEvent.getUploadEventType() == UploadEventType.UploadEventUploadPartFailed) { Log.i("uploadFile", "event change, uploadPart failed"); if (input.getCancelHook() != null) { // 调用 cancel 时,如果 isAbort 为 true,会终止断点续传,删除本地 checkpoint 文件, // 并调用 abortMultipartUpload 取消分片上传。 // 如果 isAbort 为 false,只会暂停当前上传任务,再次调用 uploadFile 可从断点处续传。 input.getCancelHook().cancel(isAbort); } } } }; input.setCancelHook(true).setUploadEventListener(listener); UploadFileV2Output output = tos.uploadFile(input); Log.i("uploadFile", "uploadFile succeed, object's etag is " + output.getEtag()); Log.i("uploadFile", "uploadFile succeed, object's crc64 is " + output.getHashCrc64ecma()); } catch (TosException e) { Log.e("TosException","uploadFile failed"); e.printStackTrace(); } } }); tosThread.start(); } }