Sobes.tech
Middle

Kaip įgyvendintumėte failų įkėlimą per programėlę į serverį?

sobes.tech AI

Atsakymas iš AI

Priklausomai nuo failo dydžio, patikimumo reikalavimų ir serverio galimybių, galima naudoti keletą metodų:

1. HTTP POST užklausa su multipart/form-data:

Tai standartinis būdas siųsti failus per HTTP:

// Pavyzdys naudojant Retrofit ir OkHttp
interface FileUploadService {
    @Multipart
    @POST("/upload")
    suspend fun uploadFile(
        @Part file: MultipartBody.Part
    ): Response<ResponseBody>
}

// Kode
val file = File("kelias/iki/failo.txt")
val requestFile = file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
val body = MultipartBody.Part.createFormData("file", file.name, requestFile)

val service = retrofit.create(FileUploadService::class.java)
val response = service.uploadFile(body)
  • Privalumai: Standartinis, plačiai palaikomas metodas.
  • Trūkumai: Dideliems failams gali būti neefektyvus, nes visas failas įkeliama į atmintį, taip pat nėra galimybės atnaujinti nutrauktą siuntimą.

2. Asinchroninės siuntimo bibliotekos:

Pavyzdžiui, naudojant OkHttp, kuris leidžia siųsti failus srauto režimu, tai yra efektyviau dideliems failams:

// Pavyzdys naudojant OkHttp
val client = OkHttpClient()
val file = File("kelias/iki/didelio/failo.zip")

val requestBody = file.asRequestBody("application/octet-stream".toMediaTypeOrNull())

val request = Request.Builder()
    .url("http://jusu_serveris/upload")
    .post(requestBody)
    .build()

client.newCall(request).enqueue(object : Callback {
    override fun onFailure(call: Call, e: IOException) {
        // Klaidos apdorojimas
    }

    override fun onResponse(call: Call, response: Response) {
        if (response.isSuccessful) {
            // Sėkmingas įkėlimas
        } else {
            // Klaidos apdorojimas
        }
    }
})
  • Privalumai: Efektyvus dideliems failams, siuntimas srauto režimu, didesnė lankstumas.
  • Trūkumai: Reikalauja daugiau kodo progresse ir klaidų valdymui.

3. Foninės paslaugos su atnaujinimo galimybe (WorkManager):

Patikimam foniniam įkėlimui, ypač ilgiems procesams ar nutraukus ryšį, rekomenduojama naudoti WorkManager. Ji užtikrina užduočių vykdymą net ir uždarius programą ar perkrovus įrenginį:

Kodo pavyzdys:

// Failo įkėlimo užklausos pavyzdys
val uploadRequest = OneTimeWorkRequestBuilder<FileUploadWorker>()
    .setInputData(
        workDataOf(
            FileUploadWorker.KEY_FILE_URI to fileUri.toString(),
            FileUploadWorker.KEY_UPLOAD_URL to "http://jusu_serveris/upload"
        )
    )
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.METERED) // Tik jei yra tinklas
            .build()
    )
    .build()

WorkManager.getInstance(context).enqueue(uploadRequest)

// FileUploadWorker pavyzdys (įgyvendinimas Worker viduje)
class FileUploadWorker(
    appContext: Context,
    workerParams: WorkerParameters
) : CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result {
        val fileUriString = inputData.getString(KEY_FILE_URI) ?: return Result.failure()
        val uploadUrl = inputData.getString(KEY_UPLOAD_URL) ?: return Result.failure()
        val fileUri = Uri.parse(fileUriString)

        // Failo įkėlimo logika naudojant OkHttp ar kitą biblioteką
        // Progresso ir klaidų valdymas

        return try {
            // Tarkime, funkcija uploadFileBlockingAsync() atlieka įkėlimą
            uploadFileBlockingAsync(fileUri, uploadUrl)
            Result.success()
        } catch (e: Exception) {
            // Jei įvyksta klaida, WorkManager bandys pakartoti
            Result.retry()
        }
    }

    companion object {
        const val KEY_FILE_URI = "file_uri"
        const val KEY_UPLOAD_URL = "upload_url"
    }
}
  • Privalumai: Patikimas foninis įkėlimas, automatinis atnaujinimas, sistemos išteklių valdymas.
  • Trūkumai: Reikalauja daugiau konfigūracijos ir supratimo.

Pasirinkimas priklauso nuo:

  • Failo dydžio: dideliems failams tinka srauto metodas arba WorkManager.
  • Patikimumo: svarbiems įkėlimams geriausias pasirinkimas yra WorkManager.
  • Fono darbo reikalavimų: naudokite WorkManager.
  • Įgyvendinimo sudėtingumo: paprasti HTTP POST metodai yra lengvesni mažiems failams.

Papildomi svarstymai:

  • Progreso rodymas: svarbu rodyti naudotojui įkėlimo progresą, ypač dideliems failams.
  • Klaidų apdorojimas: būtina apdoroti įvairias klaidas, tokias kaip tinklo problemos, serverio klaidos ir kt.
  • Sauga: įsitikinkite, kad įkėlimas vyksta saugiu ryšiu (HTTPS).
  • Serverio apribojimai: atsižvelkite į jūsų serverio apribojimus dėl failų dydžio ir vienu metu siunčiamų užklausų skaičiaus.
  • Autentifikacija/Autorizacija: jei serveris to reikalauja, įtraukite tai į užklausas.

Dažniausiai pradėčiau nuo HTTP POST su multipart/form-data, o sudėtingesniems scenarijams ir dideliems failams pereičiau prie srauto metodo arba WorkManager naudojimo.