Sobes.tech
Middle

Jak byste implementovali nahrávání souborů přes aplikaci na server?

sobes.tech AI

Odpověď od AI

Lze použít několik přístupů v závislosti na velikosti souborů, požadavcích na spolehlivost a možnostech serveru.

1. HTTP POST požadavek s multipart/form-data:

Toto je standardní způsob odesílání souborů přes HTTP.

// Příklad s Retrofit a OkHttp
interface FileUploadService {
    @Multipart
    @POST("/upload")
    suspend fun uploadFile(
        @Part file: MultipartBody.Part
    ): Response<ResponseBody>
}

// V kódu
val file = File("cesta/k/souboru.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)
  • Výhody: Standardní, široce podporovaný přístup. Vhodné pro malé a střední soubory.
  • Nevýhody: U velkých souborů může být neefektivní kvůli načítání celého souboru do paměti před odesláním. Nemá vestavěnou podporu pro obnovení přerušeného nahrávání.

2. Knihovny pro asynchronní nahrávání:

Existují knihovny, jako je OkHttp, které umožňují odesílat soubory v proudu, což je efektivnější pro velké soubory.

// Příklad s OkHttp
val client = OkHttpClient()
val file = File("cesta/k/velkemu/souboru.zip")

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

val request = Request.Builder()
    .url("http://váš_server/upload")
    .post(requestBody)
    .build()

client.newCall(request).enqueue(object : Callback {
    override fun onFailure(call: Call, e: IOException) {
        // Zpracování chyby
    }

    override fun onResponse(call: Call, response: Response) {
        if (response.isSuccessful) {
            // Úspěšné nahrání
        } else {
            // Zpracování chyby
        }
    }
})
  • Výhody: Efektivní pro velké soubory, odesílání v proudu. Větší flexibilita.
  • Nevýhody: Vyžaduje více kódu pro sledování průběhu a chyb.

3. Služby na pozadí s podporou obnovení (WorkManager):

Pro spolehlivé nahrávání na pozadí, zejména pro dlouhé procesy nebo při přerušení spojení, se doporučuje použít WorkManager. Zajišťuje garantované provedení úkolů, i když je aplikace uzavřena nebo zařízení restartováno.

Můžete implementovat úlohu nahrávání souboru uvnitř WorkManager. Pokud dojde k přerušení, WorkManager se postará o její obnovení.

// Příklad Work Request pro nahrávání souboru
val uploadRequest = OneTimeWorkRequestBuilder<FileUploadWorker>()
    .setInputData(
        workDataOf(
            FileUploadWorker.KEY_FILE_URI to fileUri.toString(),
            FileUploadWorker.KEY_UPLOAD_URL to "http://váš_server/upload"
        )
    )
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.METERED) // Pouze při síti
            .build()
    )
    .build()

WorkManager.getInstance(context).enqueue(uploadRequest)

// Příklad FileUploadWorker (implementace uvnitř Worker)
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)

        // Implementace logiky nahrávání souboru s použitím OkHttp nebo jiné knihovny
        // Zpracování průběhu a chyb

        return try {
            // Předpokládejme, že funkce uploadFileBlockingAsync() provádí nahrávání
            uploadFileBlockingAsync(fileUri, uploadUrl)
            Result.success()
        } catch (e: Exception) {
            // Při chybě se WorkManager pokusí znovu
            Result.retry()
        }
    }

    companion object {
        const val KEY_FILE_URI = "file_uri"
        const val KEY_UPLOAD_URL = "upload_url"
    }
}
  • Výhody: Spolehlivé nahrávání na pozadí, automatické obnovení, řízení systémových zdrojů.
  • Nevýhody: Vyžaduje více nastavení a pochopení konceptu WorkManageru.

Volba přístupu závisí na:

  • Velikosti souboru: Pro velké soubory jsou vhodnější streaming nebo WorkManager.
  • Spolehlivosti: Pro kritické nahrávání s možností přerušení je nejlepší WorkManager.
  • Požadavcích na pozadí: Pokud má nahrávání běžet na pozadí, použijte WorkManager.
  • Složitosti implementace: Jednoduché HTTP POST požadavky jsou jednodušší na realizaci pro malé soubory.

Další úvahy:

  • Průběh nahrávání: Je důležité zobrazovat uživateli průběh nahrávání, zejména u velkých souborů.
  • Zpracování chyb: Je nutné řešit různé chyby, jako jsou problémy s připojením, chyby serveru a další.
  • Bezpečnost: Ujistěte se, že nahrávání probíhá přes zabezpečené spojení (HTTPS).
  • Omezení serveru: Zohledněte omezení vašeho serveru na velikost nahrávaných souborů a počet současných požadavků.
  • Autentizace/Autorizace: Pokud server vyžaduje autentizaci, zahrňte ji do požadavků na nahrávání.

Obvykle bych začal s jednoduchým HTTP POST multipart/form-data a přecházel bych na streaming nebo WorkManager s streamovým zpracováním souborů pro složitější scénáře a velké soubory.