帮你快速理解、总结文档立即下载

上传与下载

最近更新时间:2026-09-30 16:51:30
我的收藏

前期准备

开始操作前,确保您已经完成了 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();