Hi

split and upload flies to chunk kolitin

 If your current code uploads chunks in parallel, switch to sequential upload and ensure each chunk uses its own byte array.

Example full upload loop:

private suspend fun uploadFileInChunks(
context: Context,
uri: Uri,
uploadId: String,
isFile: Boolean
): Boolean {

try {

val mimeType =
context.contentResolver.getType(uri)
?: "application/octet-stream"

val fileName = getFileName(context, uri)

val chunkFiles = splitFileIntoChunks(
context,
uri,
uploadId
)

val totalChunks = chunkFiles.size

Log.d(
"ChunkUpload",
"Uploading $totalChunks chunks for $fileName"
)

for ((index, chunkFile) in chunkFiles.withIndex()) {

val blob = chunkFile.readBytes()

Log.d(
"ChunkUpload",
"UploadId=$uploadId Chunk=$index Size=${blob.size}"
)

if (index == 0) {

val header = blob
.take(32)
.joinToString("") {
"%02x".format(it)
}

Log.d(
"ChunkUpload",
"FIRST CHUNK HEADER=$header"
)
}

val requestBody =
blob.toRequestBody(
"application/octet-stream".toMediaType()
)

val chunkBody =
MultipartBody.Part.createFormData(
"chunk",
chunkFile.name,
requestBody
)

val response = if (isFile) {

ApiClient.apiFiles.uploadChunkForFiles(
uploadId = uploadId.toRequestBody("text/plain".toMediaType()),
chunkIndex = index.toString()
.toRequestBody("text/plain".toMediaType()),
totalChunks = totalChunks.toString()
.toRequestBody("text/plain".toMediaType()),
originalName = fileName
.toRequestBody("text/plain".toMediaType()),
mimeType = mimeType
.toRequestBody("text/plain".toMediaType()),
chunk = chunkBody
)

} else {

ApiClient.apiFiles.uploadChunk(
uploadId = uploadId.toRequestBody("text/plain".toMediaType()),
chunkIndex = index.toString()
.toRequestBody("text/plain".toMediaType()),
totalChunks = totalChunks.toString()
.toRequestBody("text/plain".toMediaType()),
originalName = fileName
.toRequestBody("text/plain".toMediaType()),
mimeType = mimeType
.toRequestBody("text/plain".toMediaType()),
chunk = chunkBody
)
}

if (!response.isSuccessful ||
response.body()?.ok != true
) {

Log.e(
"ChunkUpload",
"Chunk upload failed index=$index"
)

return false
}

Log.d(
"ChunkUpload",
"Chunk uploaded ${index + 1}/$totalChunks"
)
}

// Cleanup chunk files
chunkFiles.forEach {
try {
it.delete()
} catch (_: Exception) {
}
}

Log.d(
"ChunkUpload",
"All chunks uploaded successfully"
)

return true

} catch (e: Exception) {

Log.e(
"ChunkUpload",
"uploadFileInChunks failed",
e
)

return false
}
}

Update your splitFileIntoChunks() as well:



private fun splitFileIntoChunks(

    context: Context,

    uri: Uri,

    uploadId: String

): List<File> {


    val chunkFiles = mutableListOf<File>()


    context.contentResolver.openInputStream(uri)?.use { stream ->


        val buffer = ByteArray(CHUNK_SIZE)


        var bytesRead: Int

        var chunkIndex = 0


        while (stream.read(buffer).also { bytesRead = it } > 0) {


            val chunkBytes = buffer.copyOf(bytesRead)


            val chunkFile = File(

                context.cacheDir,

                "${uploadId}_${String.format("%06d", chunkIndex)}.part"

            )


            FileOutputStream(chunkFile).use {

                it.write(chunkBytes)

            }


            chunkFiles.add(chunkFile)


            chunkIndex++

        }

    }


    return chunkFiles

}

Previous
Next Post »