Cómo cargar un archivo de gran tamaño para el servidor, mediante la reconversión de varias partes

0

Pregunta

Tengo la solicitud, la cual funciona bien en cartero:

enter image description here

y estoy tratando de hacer con la modernización. En general, los tamaños de archivo será >500 MB que. Me hizo método de subida:

fun uploadFile(file:File) {

        val client = OkHttpClient().newBuilder()
            .build()
        val mediaType: MediaType? = "text/plain".toMediaTypeOrNull()
        val body: RequestBody = MultipartBody.Builder().setType(MultipartBody.FORM)
            .addFormDataPart(
                "data", file.name,
                file.asRequestBody()
            )
            .build()
        val request: Request = Request.Builder()
            .url("https://..../upload.php")
            .method("POST", body)
            .build()
        val response: okhttp3.Response = client.newCall(request).execute()

       println(response.message)
    }

pero tengo que tener el archivo para cargar. Puedo crear el archivo temporal con tal manera:

val path = requireContext().cacheDir
val file = File.createTempFile(
    name ?: "",
    fileUri.lastPathSegment,
    path
)
val os = FileOutputStream(file)
os.write(string)
os.close()

pero yo, por lo general reciben outOfMemoryException. También he añadido a la AndroidManifest.xml montón param:

android:largeHeap="true"

pero no me ayuda en absoluto durante archivo temporal de la creación. No sé cómo cartero carga de archivos, pero en general me las arreglé para subir con su archivo de ayuda con un tamaño de unos 600Mb. Yo también puedo cortar el archivo seleccionado con fragmentos:

val data = result.data
data?.let {
      val fileUri = data.data
      var name: String? = null
      var size: Long? = null
      fileUri.let { returnUri ->
            contentResolver?.query(returnUri!!, null, null, null, null)
      }?.use { cursor ->
            val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
            val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)

            cursor.moveToFirst()
            name = cursor.getString(nameIndex)
            size = cursor.getLong(sizeIndex)
       }


val inputStream: InputStream? = fileUri?.let { it1 ->
    contentResolver.openInputStream(
        it1
    )
}

val fileData = inputStream?.readBytes()
val mimeType = fileUri.let { returnUri ->
returnUri.let { retUri ->
    if (retUri != null) {
           contentResolver.getType(retUri)
    }
}
}


fileData?.let {
       val MAX_SUB_SIZE = 4194304 // 4*1024*1024 == 4MB
       var start = 0 // From 0
       var end = MAX_SUB_SIZE // To MAX_SUB_SIZE bytes
       var subData: ByteArray // 4MB Sized Array

       val max = fileData.size
       if (max > 0) {
           while (end < max) {
                subData = fileData.copyOfRange(start, end)
                start = end
                end += MAX_SUB_SIZE
                if (end >= max) {
                    end = max
                }
                                
                println("file handling" + subData.size)



        }
     end-- // To avoid a padded zero
     subData = fileData.copyOfRange(start, end)
     println("file handling" + subData.size)
     }
   }
}

todas las acciones se realizarán en:

 private val filesReceiver =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            if (result.resultCode == Activity.RESULT_OK) {

             }
         }

así que no tengo ninguna ruta de acceso del archivo en forma normal. De todos modos creo que hice algo mal.

ACTUALIZACIÓN

ahora mismo tengo cargando archivo de inputStream:

 private fun doSomeNetworkStuff(file:InputStream, name:String) {
        GlobalScope.launch(Dispatchers.IO) {
            val client = OkHttpClient()
                .newBuilder()
                .protocols(listOf(Protocol.HTTP_1_1))
                .connectTimeout(10, TimeUnit.MINUTES)
                .readTimeout(10, TimeUnit.MINUTES)
                .build()
            val mediaType: MediaType? = "text/plain".toMediaTypeOrNull()
            val body: RequestBody = MultipartBody.Builder().setType(MultipartBody.FORM)
                .addFormDataPart(
                    "data", name,
                    file.readBytes().toRequestBody(mediaType)
                )
                .build()
            val request: Request = Request.Builder()
                .url("https://.../upload.php")
                .method("POST", body)
                .build()

            val response: Response = client.newCall(request).execute()

            println(response.body)
        }
    }

y recibir de error:

java.lang.OutOfMemoryError: Failed to allocate a 173410912 byte allocation with 25165824 free bytes and 89MB until OOM, max allowed footprint 199761800, growth limit 268435456

pero puedo cargar con este archivo de código con un tamaño de unos 90mb

android
2021-11-24 05:56:49
2

Mejor respuesta

1

La reconversión de varias cosas, un miembro que tiene una Uri para un cuerpo de solicitud.

Intenta utilizar una para un Archivo de ejemplo.

2021-11-24 07:53:27

puede usted aclarar pls que el personal, porque he visto esta pregunta stackoverflow.com/questions/34562950/... y utiliza el personal de él
Andrew

Hizo ver somerhing para una uri no? Para una secuencia de entrada?
blackapps

Google para inputstreamrequestbody.
blackapps

He intentado utilizar el flujo de entrada como usted ha dicho, pero con una matriz de bytes de uso, y mi método de subida falla en el tamaño del archivo > 90mb, se puede comprobar mi pregunta upd pls?
Andrew

Hice sólo decir que el uso de la uri. Parece que no están haciendo eso. Usted no debe usar una matriz de bytes. O una secuencia de entrada. Bueno... No de esta manera.
blackapps

tal vez usted puede agregar algunos ejemplos, porque lo hice como entiende usted, tal vez usted conoce mejor que yo?) porque yo no encuentro ninguna se menciona acerca de uri para requestbody
Andrew

0

Te has fijado registro en loggingInterceptor o restadapter ?
si sí, entonces intenta establecer que NINGUNO.

2021-11-24 06:14:28

ya está hecho
Andrew

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................