العمل مع S3 والتخزين السحابي في Kotlin
أصبحت مخازن الكائنات السحابية المتوافقة مع بروتوكول Amazon S3 (Simple Storage Service) المعيار الفعلي لتخزين البيانات غير المهيكلة: الصور، الفيديوهات، السجلات، النسخ الاحتياطية، وقطع البناء. في نظام Kotlin البيئي (JVM، Android، Kotlin Multiplatform) يتم استخدام نهجين رئيسيين للتفاعل مع S3: AWS SDK for Java/Kotlin الرسمي و MinIO Java SDK خفيف الوزن. في هذه المقالة سنشرح كلا الخيارين، ونعرض أمثلة على الكود، ونقدم توصيات للاختيار.
1. AWS SDK for Java (Kotlin)
يدعم SDK الرسمي من Amazon جميع إمكانيات S3، بما في ذلك التحميل متعدد الخيوط، إدارة دورة الحياة، التحكم في الإصدارات، والتشفير. بالنسبة لـ Kotlin، يكفي إضافة التبعية في build.gradle.kts:
dependencies { implementation("software.amazon.awssdk:s3:2.27.0") implementation("software.amazon.awssdk:auth:2.27.0")}مثال أساسي لرفع ملف إلى حاوية S3:
import software.amazon.awssdk.auth.credentials.AwsBasicCredentialsimport software.amazon.awssdk.auth.credentials.StaticCredentialsProviderimport software.amazon.awssdk.regions.Regionimport software.amazon.awssdk.services.s3.S3Clientimport software.amazon.awssdk.services.s3.model.PutObjectRequestimport java.nio.file.Paths
fun main() { val credentials = AwsBasicCredentials.create("ACCESS_KEY", "SECRET_KEY") val s3 = S3Client.builder() .region(Region.EU_CENTRAL_1) .credentialsProvider(StaticCredentialsProvider.create(credentials)) .build()
val request = PutObjectRequest.builder() .bucket("my-bucket") .key("uploads/photo.jpg") .contentType("image/jpeg") .build()
s3.putObject(request, Paths.get("/local/path/photo.jpg")) println("تم رفع الملف")}تنزيل كائن:
import software.amazon.awssdk.services.s3.model.GetObjectRequest
val getRequest = GetObjectRequest.builder() .bucket("my-bucket") .key("uploads/photo.jpg") .build()
s3.getObject(getRequest, Paths.get("/local/download/photo.jpg"))2. MinIO Java SDK (تخزين متوافق مع S3)
MinIO هو مخزن كائنات عالي الأداء مفتوح المصدر، متوافق تمامًا مع S3 API. SDK الخاص به مناسب للعمل مع MinIO المحلي، وكذلك مع AWS S3، DigitalOcean Spaces، Yandex Object Storage، وغيرها من المزودين. أضف التبعية:
dependencies { implementation("io.minio:minio:8.5.10")}مثال لرفع ملف عبر MinIO SDK:
import io.minio.MinioClientimport io.minio.PutObjectArgsimport java.io.FileInputStream
fun main() { val minioClient = MinioClient.builder() .endpoint("https://play.min.io") .credentials("minioadmin", "minioadmin") .build()
val inputStream = FileInputStream("/local/data/report.pdf") minioClient.putObject( PutObjectArgs.builder() .bucket("documents") .`object`("reports/2024/report.pdf") .stream(inputStream, inputStream.available(), -1) .contentType("application/pdf") .build() ) println("تم رفع الملف إلى MinIO")}تنزيل عبر MinIO:
import io.minio.GetObjectArgsimport java.io.FileOutputStream
val getArgs = GetObjectArgs.builder() .bucket("documents") .`object`("reports/2024/report.pdf") .build()
val response = minioClient.getObject(getArgs)response.use { stream -> FileOutputStream("/local/download/report.pdf").use { output -> stream.transferTo(output) }}3. العمل مع الروابط العامة وصلاحيات الصلاحية
إنشاء رابط مؤقت (presigned URL) للتنزيل بدون