在 Kotlin 中使用 S3 和云存储
在现代 Kotlin 开发中,经常需要与兼容 Amazon S3(简单存储服务)协议的云存储集成。这些存储包括 AWS S3、MinIO、DigitalOcean Spaces、Yandex Object Storage 等。在本文中,我们将探讨两种主要方法:使用官方的 AWS SDK for Kotlin 和基于 Ktor 的轻量级客户端。
1. AWS SDK for Kotlin (aws-sdk-kotlin)
Amazon 提供的官方 SDK 提供了类型安全且异步的 API,完全支持 Kotlin 协程。这是处理 S3 最全面的解决方案。
添加依赖
在 build.gradle.kts 中添加:
dependencies { implementation("aws.sdk.kotlin:s3:1.0.0") implementation("aws.smithy.kotlin:http-client-engine-ktor:1.0.0")}初始化客户端
import aws.sdk.kotlin.services.s3.S3Clientimport aws.sdk.kotlin.services.s3.model.*
suspend fun createClient(): S3Client = S3Client.fromEnvironment { region = "ru-central1" // 对于 MinIO 或其他兼容 S3 的存储: endpointUrl = "https://storage.yandexcloud.net" // 通过环境变量 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 进行配置}上传文件 (PutObject)
suspend fun uploadFile(client: S3Client, bucket: String, key: String, filePath: String) { val fileBytes = java.io.File(filePath).readBytes() client.putObject( PutObjectRequest { this.bucket = bucket this.key = key this.body = fileBytes.toByteArray() } ) println("文件 $key 已上传到存储桶 $bucket")}下载文件 (GetObject)
suspend fun downloadFile(client: S3Client, bucket: String, key: String, savePath: String) { val response = client.getObject( GetObjectRequest { this.bucket = bucket this.key = key } ) val bytes = response.body?.readAll() if (bytes != null) { java.io.File(savePath).writeBytes(bytes) println("文件 $key 已保存到 $savePath") }}列出存储桶中的对象
suspend fun listObjects(client: S3Client, bucket: String): List<String> { val response = client.listObjectsV2( ListObjectsV2Request { this.bucket = bucket } ) return response.contents?.map { it.key ?: "" } ?: emptyList()}2. Ktor S3 客户端(轻量级替代方案)
如果您不需要 AWS SDK 的全部功能,可以使用 Ktor 配合 ktor-client-s3 库。这提供了最小的体积和对 HTTP 请求的完全控制。
添加依赖
dependencies { implementation("io.ktor:ktor-client-core:2.3.0") implementation("io.ktor:ktor-client-cio:2.3.0") implementation("io.ktor:ktor-client-content-negotiation:2.3.0") implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.0") // 用于 S3 请求签名 implementation("io.ktor:ktor-client-auth:2.3.0")}基于 Ktor 创建 S3 客户端
import io.ktor.client.*import io.ktor.client.request.*import io.ktor.client.statement.*import io.ktor.http.*import io.ktor.utils.io.*
class S3KtorClient( private val endpoint: String, private val accessKey: String, private val secretKey: String) { private val client = HttpClient { install(io.ktor.client.plugins.auth.Auth) { basic { credentials { username = accessKey password = secretKey } } } }
suspend fun putObject(bucket: String, key: String, data: ByteArray) { client.put("