前期准备
开始操作前,确保您已经完成了 SDK 初始化。如果您还没有初始化 SDK,请先参考快速入门文档完成。
Java SDK 通过
SmhClient 的 uploadFile 和 downloadFile 方法提供文件上传和下载功能,使用前需要导入相关类:import com.tencent.cloud.smh.transfer.UploadOptions;import com.tencent.cloud.smh.transfer.DownloadOptions;import com.tencent.cloud.smh.transfer.UploadResult;import com.tencent.cloud.smh.transfer.exception.TransferCancelledException;
上传文件
本文介绍如何通过 SMH Java SDK 进行文件上传。Java SDK 支持简单上传和分块上传两种模式,根据文件大小自动选择上传方式。
功能特性
简单上传 - 适用于小文件的直接上传
分块上传 - 大文件自动分块并发上传,提升上传速度
秒传功能 - 文件 hash 匹配时直接完成上传,无需重新上传
进度监控 - 通过回调函数实时获取上传进度
取消上传 - 支持取消正在进行的上传任务
快速开始
Fluent API 模式
UploadOptions options = new UploadOptions().setLibraryId("your-library-id").setSpaceId("your-space-id").setFilePath("/remote/path/file.txt").setLocalPath("/local/path/file.txt").setAccessToken("your-access-token").setChunkSizeMB(10) // 10MB 分块大小.setPartFileSizeMB(50) // 超过 50MB 的文件使用分块上传.setParallel(5) // 5 个并发上传.setOnProgress(progress -> System.out.printf("Upload progress: %.1f%%\\n", progress));try {UploadResult result = client.uploadFile(options);System.out.printf("Upload completed: Name=%s, Inode=%s, Size=%s%n",result.getName(), result.getInode(), result.getSize());} catch (Exception e) {System.err.println("Upload failed: " + e.getMessage());}
Builder 模式
UploadOptions options = UploadOptions.builder().libraryId("your-library-id").spaceId("your-space-id").filePath("/remote/path/file.txt").localPath("/local/path/file.txt").accessToken("your-access-token").chunkSizeMB(10).partFileSizeMB(50).parallel(5).onProgress(progress -> System.out.printf("Upload progress: %.1f%%\\n", progress)).build();try {UploadResult result = client.uploadFile(options);System.out.printf("Upload completed: Name=%s, Inode=%s, Size=%s%n",result.getName(), result.getInode(), result.getSize());} catch (Exception e) {System.err.println("Upload failed: " + e.getMessage());}
参数说明
uploadFile 方法签名:public UploadResult uploadFile(UploadOptions options) throws ApiException, IOException
UploadOptions 参数表
参数名 | 类型 | 必填 | 说明 |
libraryId | String | 是 | 媒体库 ID |
spaceId | String | 是 | 空间 ID |
filePath | String | 是 | 远端文件路径 |
localPath | String | 是 | 本地文件路径 |
accessToken | String | 是 | 访问令牌;对于公有读媒体库或租户空间可不指定,否则需通过本参数传入或提前调用 client.withToken() 注入,二者取一 |
userId | String | 否 | 用户身份识别,当访问令牌对应的权限为管理员权限且申请访问令牌时的用户身份识别为空时用来临时指定用户身份 |
chunkSizeMB | long | 否 | 分块大小,单位:MB,默认值:1MB |
parallel | int | 否 | 并发上传数,默认值:5 |
partFileSizeMB | long | 否 | 分块上传阈值,单位:MB,超过此大小的文件使用分块上传,默认值:32MB,范围:1MB - 5GB |
conflictResolutionStrategy | String | 否 | 冲突解决策略,默认值:rename。可选值:rename(重命名)/ ask(询问)/ overwrite(覆盖) |
enableInstantUpload | boolean | 否 | 是否启用秒传功能,默认值:false |
trafficLimit | Long | 否 | 上传限速,单位:字节/秒 |
preferSameOrigin | boolean | 否 | 是否优先使用同源上传,默认值:false |
labels | List<String> | 否 | 文件标签列表 |
category | String | 否 | 文件自定义的分类 |
localCreationTime | String | 否 | 文件对应的本地创建时间 |
localModificationTime | String | 否 | 文件对应的本地修改时间 |
onProgress | Consumer<Double> | 否 | 进度回调函数,参数为上传进度百分比(0-100),200ms 节流 |
onSpeedInfo | Consumer<SpeedInfo> | 否 | 速度回调函数,1s 采样;SpeedInfo 为 TransferOptions 的静态内部类(com.tencent.cloud.smh.transfer.TransferOptions.SpeedInfo),包含 speed(瞬时速度 B/s)、avgSpeed(平均速度 B/s)、leftTime(预计剩余秒)、loaded(已传字节)、totalSize(总字节)、progress(百分比) |
UploadResult 返回值说明
上传成功后返回
UploadResult 对象,包含上传文件的详细信息。字段 | 类型 | 说明 |
path | List<String> | 最终文件路径,数组中最后一个元素代表最终文件名,其他元素代表每一级目录名 |
name | String | 最终文件名(冲突策略为 rename 时可能与请求的文件名不同) |
type | String | 文件类型 |
inode | String | 文件 ID,可用于后续文件操作 |
size | String | 文件大小,字符串格式 |
crc64 | String | 文件 CRC64-ECMA182 校验值,字符串格式 |
eTag | String | 文件 ETag |
creationTime | OffsetDateTime | 文件首次完成上传的时间 |
modificationTime | OffsetDateTime | 文件最近一次被覆盖的时间 |
contentType | String | 媒体类型 |
isOverwritten | boolean | 文件上传时是否发生文件覆盖 |
fileType | String | 文件类型分类(如 excel、powerpoint 等) |
metaData | Map<String, String> | 元数据键值对 |
rapidUpload | boolean | 是否秒传成功(文件 hash 匹配直接完成上传) |
virusAuditStatus | Integer | 病毒检测状态 |
previewByDoc | Boolean | 是否支持文档预览(WPS) |
previewByCI | Boolean | 是否支持数据万象预览 |
previewAsIcon | Boolean | 是否支持缩略图预览 |
上传模式
Java SDK 通过
uploadFile 方法提供文件上传功能。SDK 会根据文件大小自动选择简单上传或分块上传模式,无需手动切换。简单上传
适用于小文件(文件大小小于
partFileSizeMB,默认 32MB),SDK 自动使用简单上传模式,一次请求完成上传。UploadOptions options = new UploadOptions().setLibraryId("your-library-id").setSpaceId("your-space-id").setFilePath("/uploads/small-file.txt").setLocalPath("/path/to/local/small-file.txt").setAccessToken("your-access-token");try {UploadResult result = client.uploadFile(options);System.out.println("Upload completed!");} catch (Exception e) {System.err.println("Upload failed: " + e.getMessage());}
分块上传
适用于大文件(文件大小超过
partFileSizeMB),SDK 自动将文件分块并发上传,单个分块失败会自动重试(默认重试 3 次,指数退避),局部网络抖动不会导致整个文件重新上传。UploadOptions options = UploadOptions.builder().libraryId("your-library-id").spaceId("your-space-id").filePath("/uploads/large-video.mp4").localPath("/path/to/local/large-video.mp4").accessToken("your-access-token").chunkSizeMB(5) // 每个分块 5MB.parallel(3) // 同时上传 3 个分块.partFileSizeMB(32) // 超过 32MB 使用分块上传.onProgress(progress -> System.out.printf("Upload progress: %.1f%%\\n", progress)).build();try {UploadResult result = client.uploadFile(options);System.out.println("Upload completed!");} catch (Exception e) {System.err.println("Upload failed: " + e.getMessage());}
秒传功能
秒传功能可以大幅提升上传效率,当后端检测到文件已存在时,直接返回成功,无需重新上传。
SDK 会自动计算文件的哈希值,服务端匹配后确认文件已存在即可完成秒传。文件大小需 ≥ 1MB 才会触发秒传检测。
UploadOptions options = new UploadOptions().setLibraryId("your-library-id").setSpaceId("your-space-id").setFilePath("/uploads/existing-file.txt").setLocalPath("/path/to/local/existing-file.txt").setAccessToken("your-access-token").setEnableInstantUpload(true); // 启用秒传try {UploadResult result = client.uploadFile(options);// 通过 isRapidUpload 判断是否秒传成功if (result.isRapidUpload()) {System.out.println("秒传成功!文件已存在,无需上传。");} else {System.out.println("上传成功!文件已上传完成。");}} catch (Exception e) {System.err.println("Upload failed: " + e.getMessage());}
取消上传
由于
uploadFile 是同步阻塞调用,如需取消正在进行的上传,可以在另一个线程中调用 UploadOptions 的 cancel() 方法,上传线程会抛出 TransferCancelledException。UploadOptions options = new UploadOptions().setLibraryId("your-library-id").setSpaceId("your-space-id").setFilePath("/uploads/large-video.mp4").setLocalPath("/path/to/local/large-video.mp4").setAccessToken("your-access-token").setOnProgress(progress -> {System.out.printf("Upload progress: %.1f%%\\n", progress);});// 在上传线程中执行ExecutorService executor = Executors.newSingleThreadExecutor();Future<?> future = executor.submit(() -> {try {client.uploadFile(options);} catch (TransferCancelledException e) {System.out.println("上传已取消");} catch (Exception e) {System.err.println("Upload failed: " + e.getMessage());}});// 需要取消时,在另一个线程中调用options.cancel();
下载文件
本文介绍如何通过 SMH Java SDK 进行文件下载。Java SDK 支持简单下载和分块下载两种模式,根据文件大小自动选择下载方式。
功能特性
简单下载 - 适用于小文件的直接下载
分块下载 - 大文件自动分块并发下载,提升下载速度
进度监控 - 通过回调函数实时获取下载进度
取消下载 - 支持取消正在进行的下载任务
快速开始
Fluent API 模式
DownloadOptions options = new DownloadOptions().setLibraryId("your-library-id").setSpaceId("your-space-id").setFilePath("/remote/path/file.txt").setLocalPath("/local/save/file.txt").setAccessToken("your-access-token").setChunkSizeMB(10) // 10MB 分块大小.setPartFileSizeMB(50) // 超过 50MB 的文件使用分块下载.setParallel(5) // 5 个并发下载.setOnProgress(progress -> System.out.printf("Download progress: %.1f%%\\n", progress));try {client.downloadFile(options);System.out.println("Download completed!");} catch (Exception e) {System.err.println("Download failed: " + e.getMessage());}
Builder 模式
DownloadOptions options = DownloadOptions.builder().libraryId("your-library-id").spaceId("your-space-id").filePath("/remote/path/file.txt").localPath("/local/save/file.txt").accessToken("your-access-token").chunkSizeMB(10).partFileSizeMB(50).parallel(5).onProgress(progress -> System.out.printf("Download progress: %.1f%%\\n", progress)).build();try {client.downloadFile(options);System.out.println("Download completed!");} catch (Exception e) {System.err.println("Download failed: " + e.getMessage());}
参数说明
downloadFile 方法签名:public void downloadFile(DownloadOptions options) throws ApiException, IOException
DownloadOptions 参数表
参数名 | 类型 | 必填 | 说明 |
libraryId | String | 是 | 媒体库 ID |
spaceId | String | 是 | 空间 ID |
filePath | String | 是 | 远程文件路径 |
localPath | String | 是 | 本地保存路径 |
accessToken | String | 是 | 访问令牌;对于公有读媒体库或租户空间可不指定,否则需通过本参数传入或提前调用 client.withToken() 注入,二者取一 |
userId | String | 否 | 用户身份识别,当访问令牌对应的权限为管理员权限且申请访问令牌时的用户身份识别为空时用来临时指定用户身份 |
chunkSizeMB | long | 否 | 分块大小,单位:MB,默认值:1MB |
parallel | int | 否 | 并发下载数,默认值:5 |
partFileSizeMB | long | 否 | 分块下载阈值,单位:MB,超过此大小的文件使用分块下载,默认值:32MB |
trafficLimit | Long | 否 | 下载限速,单位:字节/秒 |
onProgress | Consumer<Double> | 否 | 进度回调函数,参数为下载进度百分比(0-100),200ms 节流 |
onSpeedInfo | Consumer<SpeedInfo> | 否 | 速度回调函数,1s 采样;SpeedInfo 为 TransferOptions 的静态内部类(com.tencent.cloud.smh.transfer.TransferOptions.SpeedInfo),包含 speed(瞬时速度 B/s)、avgSpeed(平均速度 B/s)、leftTime(预计剩余秒)、loaded(已下载字节)、totalSize(总字节)、progress(百分比) |
下载模式
SDK 根据文件大小自动选择下载模式,无需手动切换。
1. 简单下载
适用于小文件(小于
partFileSizeMB,默认 32MB),使用单个请求完成下载。DownloadOptions options = new DownloadOptions().setLibraryId("your-library-id").setSpaceId("your-space-id").setFilePath("/downloads/small-file.txt").setLocalPath("/path/to/local/small-file.txt").setAccessToken("your-access-token");try {client.downloadFile(options);System.out.println("Download completed!");} catch (Exception e) {System.err.println("Download failed: " + e.getMessage());}
2. 分块下载
适用于大文件(大于
partFileSizeMB),自动分块并发下载。每个分块使用 HTTP Range 请求下载,下载完成后自动合并为完整文件。下载过程先写入 本地路径 + .download.part 临时文件,CRC64/大小校验通过后原子改名为目标文件;若本地已存在同名文件且大小一致则跳过下载;下载地址超过 1 小时会自动刷新,长时间下载不会因链接过期失败。DownloadOptions options = DownloadOptions.builder().libraryId("your-library-id").spaceId("your-space-id").filePath("/downloads/large-video.mp4").localPath("/path/to/local/large-video.mp4").accessToken("your-access-token").chunkSizeMB(5) // 每个分块 5MB.parallel(3) // 同时下载 3 个分块.partFileSizeMB(32) // 超过 32MB 使用分块下载.onProgress(progress -> System.out.printf("Download progress: %.1f%%\\n", progress)).build();try {client.downloadFile(options);System.out.println("Download completed!");} catch (Exception e) {System.err.println("Download failed: " + e.getMessage());}
取消下载
由于
downloadFile 是同步阻塞调用,如需取消正在进行的下载,可以在另一个线程中调用 DownloadOptions 的 cancel() 方法,下载线程会抛出 TransferCancelledException。DownloadOptions options = new DownloadOptions().setLibraryId("your-library-id").setSpaceId("your-space-id").setFilePath("/downloads/large-video.mp4").setLocalPath("/path/to/local/large-video.mp4").setAccessToken("your-access-token").setOnProgress(progress -> {System.out.printf("Download progress: %.1f%%\\n", progress);});// 在下载线程中执行ExecutorService executor = Executors.newSingleThreadExecutor();Future<?> future = executor.submit(() -> {try {client.downloadFile(options);} catch (TransferCancelledException e) {System.out.println("下载已取消");} catch (Exception e) {System.err.println("Download failed: " + e.getMessage());}});// 需要取消时,在另一个线程中调用options.cancel();