最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android 文件分段上傳和下載實現(xiàn)方案

 更新時間:2024年11月22日 14:37:25   作者:粵M溫同學(xué)  
文章介紹了Android大文件下載和上傳的分段處理方法,在下載時,使用多線程并發(fā)請求文件的多個段,并將這些段寫入同一個文件,在上傳時,根據(jù)文件大小分段上傳,每段文件的大小由預(yù)設(shè)閾值決定,感興趣的朋友跟隨小編一起看看吧

一、背景

Android 中的大文件下載需要使用分段下載,下載通常是在線程中進行的,假如有5段,那同時5個線程去執(zhí)行下載,請求http返回文件流后,需要將多個文件流同時寫進同一個文件,這里用到

RandomAccessFile

分段上傳的話,只需要根據(jù)每段文件閥值,例如,50M為一段,將文件按照設(shè)置的閥值,分段上傳即可

二、相關(guān)代碼

2.1 分段上傳關(guān)鍵代碼

忽略網(wǎng)絡(luò)請求和狀態(tài)碼,每個人接口定義的的請求參數(shù)和返回code不一樣

       private val DEFAULT_BLOCK_SIZE: Long = 50 * 1024 * 1024 //50MB
        val blockSize=DEFAULT_BLOCK_SIZE
        val randomAccessFile = RandomAccessFile(filePath, "r")
        val fileLen = randomAccessFile.length()
        //超過設(shè)定的單個文件大小,需要分塊上傳
            val blockFileNum = Math.ceil((fileLen / blockSize.toDouble())).toInt()
            XLogUtil.d("${TAG}blockFileNum:$blockFileNum,,,,fileLen:$fileLen,,,blockSize:$blockSize,,,requestId:$requestId")
            var offSet = 0L
            var successNum = 0
            var isSendResult = true
            for (i in 0 until blockFileNum) {
                val startOffset = i * blockSize
                val blockFileLen = Math.min(blockSize, fileLen - startOffset)
                val fileData = getFileData(filePath, offSet, blockFileLen.toInt())
                // 創(chuàng)建文件名請求體
                val requestBody = RequestBody.create(null, fileData)
                val call = RetrofitClient.getUploadFileService(
                    token,
                    requestId,
                    offSet.toString(),
                    uploadType
                ).uploadFile(file.name, requestBody)
                XLogUtil.d("${TAG}upload 第${i + 1}塊 block file,offSet:$offSet,,,blockFileLen:$blockFileLen,,,blockFileNum:$blockFileNum,,,fileLen:$fileLen,,,filePath:$filePath,,,fileData size:${fileData?.size},,,requestId:$requestId")
                offSet += blockFileLen
                call.enqueue(object : Callback<ResponseBody?> {
                    override fun onResponse(
                        call: Call<ResponseBody?>,
                        response: Response<ResponseBody?>
                    ) {
                        val code = response.code()
                        XLogUtil.d("${TAG}upload 第${i + 1}塊 block file result code:$code,,,requestId:$requestId")
                        if (code == 201) {
                            //處理成功響應(yīng)
                            successNum++
                            if (successNum == blockFileNum) {
                                XLogUtil.d("${TAG}upload all block file success,blockFileNum:$blockFileNum,,,requestId:$requestId")
                                listener?.apply {
                                    onSuccess(Constant.SUCCESS, requestId)
                                }
                                //上傳完
                            }
                        } else {
                            //處理失敗響應(yīng)
                        }
                    }
                    override fun onFailure(call: Call<ResponseBody?>, t: Throwable) {
                        // 處理請求失敗
                        XLogUtil.d("${TAG}upload 第${i + 1}塊 block file onFailure message:${t.printStackTrace()}")
                    }
                })
            }
    /**
     * 根據(jù)偏移量獲取分塊文件數(shù)據(jù)
     */
    fun getFileData(filePath: String, offset: Long, length: Int): ByteArray? {
        // 使用RandomAccessFile隨機訪問文件
        var randomAccessFile: RandomAccessFile? = null
        try {
            randomAccessFile = RandomAccessFile(filePath, "r")
            val fileChannel = randomAccessFile.channel
            // 將文件的部分區(qū)域映射為內(nèi)存區(qū)域
            val mappedByteBuffer =
                fileChannel.map(FileChannel.MapMode.READ_ONLY, offset, length.toLong())
            val data = ByteArray(length)
            // 從映射區(qū)域中讀取數(shù)據(jù)
            mappedByteBuffer[data]
            return data
        } catch (e: Exception) {
            e.printStackTrace()
            return null
        } finally {
            if (randomAccessFile != null) {
                try {
                    randomAccessFile.close()
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    }

2.2、分段下載關(guān)鍵代碼

                val folder = File(DOWNLOAD_FOLDER_PATH)
                            if (!folder.exists()) {
                                folder.mkdirs()
                            }
                            val fileName = getFileNameWithPath(filePath)
                            val downFile = File(DOWNLOAD_FOLDER_PATH + File.separator + fileName)
                            if (!downFile.exists()) {
                                downFile.createNewFile()
                            }
                            // 使用輸入流保存響應(yīng)體到文件,這里通常是通過http請求,返回的文件流,替換即可
                            val inputStream = body.byteStream()
                            val rw = RandomAccessFile(downFile, "rw")
                            rw.seek(startPosition)//文件寫入的初始位置
                            var hasReads = 0
                            var readLenght: Long = 0
                            val bytes = ByteArray(4096)
                            while ((inputStream.read(bytes).also { hasReads = it }) > 0) {
                                rw.write(bytes, 0, hasReads)
                                readLenght += hasReads
                                // val l = (readLenght * 100 / contentLength) as Int 單塊文件寫入進度
                            }
                            // 關(guān)閉文件輸出流和輸入流
                            inputStream.close()
                            rw.close()
    /**
     * 根據(jù)文件路徑獲取文件名
     */
    fun getFileNameWithPath(path: String): String {
        if (TextUtils.isEmpty(path)) {
            return ""
        }
        val start = path.lastIndexOf("/")
        return if (start != -1) {
            path.substring(start + 1)
        } else {
            "DEFAULT_NAME"
        }
    }

到此這篇關(guān)于Android 文件分段上傳和下載實現(xiàn)方案的文章就介紹到這了,更多相關(guān)Android 文件分段上傳和下載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 智能指針與弱引用詳解

    智能指針與弱引用詳解

    智能指針有很多實現(xiàn)方式,android 中的sp 句柄類實際上就是google 實現(xiàn)的一種強引用的智能指針。我沒有仔細看android sp 的實現(xiàn)方式,但其基本原理是固定的,現(xiàn)在我們從一個相對簡單的例子來看智能指針的實現(xiàn)
    2013-09-09
  • android自定義進度條移動效果

    android自定義進度條移動效果

    這篇文章主要為大家詳細介紹了android自定義進度條移動效果,進度數(shù)字隨進度移動,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • Android版的股票行情K線圖開發(fā)

    Android版的股票行情K線圖開發(fā)

    這篇文章主要介紹了Android版的股票行情K線圖開發(fā),感興趣的小伙伴們可以參考一下
    2016-01-01
  • Flutter路由傳遞參數(shù)及解析實現(xiàn)

    Flutter路由傳遞參數(shù)及解析實現(xiàn)

    這篇文章介紹了Flutter路由傳遞參數(shù)及解析實現(xiàn)的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-11-11
  • Android Native庫的加載及動態(tài)鏈接的過程

    Android Native庫的加載及動態(tài)鏈接的過程

    這篇文章主要介紹了Android Native庫的加載及動態(tài)鏈接的加載過程,需要的朋友可以參考下
    2018-01-01
  • Android 5.0+ 屏幕錄制實現(xiàn)的示例代碼

    Android 5.0+ 屏幕錄制實現(xiàn)的示例代碼

    這篇文章主要介紹了Android 5.0+ 屏幕錄制實現(xiàn)的示例代碼,從 5.0 開始,系統(tǒng)提供給了 app 錄制屏幕的一系列方法,不需要 root 權(quán)限,只需要用戶授權(quán)即可錄屏,相對來說較為簡單,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Android實現(xiàn)游戲中的漸隱和漸現(xiàn)動畫效果

    Android實現(xiàn)游戲中的漸隱和漸現(xiàn)動畫效果

    本文給大家分享android中實現(xiàn)游戲中的漸隱漸現(xiàn)的動畫效果,在游戲開發(fā)中經(jīng)常會遇到,對android漸隱漸現(xiàn)效果感興趣的朋友可以參考下本教程
    2016-09-09
  • Android TabWidget切換卡的實現(xiàn)應(yīng)用

    Android TabWidget切換卡的實現(xiàn)應(yīng)用

    本篇文章小編為大家介紹,Android TabWidget切換卡的實現(xiàn)應(yīng)用。需要的朋友參考下
    2013-04-04
  • Android垃圾回收機制及程序優(yōu)化System.gc

    Android垃圾回收機制及程序優(yōu)化System.gc

    這篇文章主要介紹了Android垃圾回收機制及程序優(yōu)化System.gc的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • Android制作登錄頁面并且記住賬號密碼功能的實現(xiàn)代碼

    Android制作登錄頁面并且記住賬號密碼功能的實現(xiàn)代碼

    這篇文章主要介紹了Android制作登錄頁面并且記住賬號密碼功能的實現(xiàn)代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04

最新評論

乌兰察布市| 集安市| 横山县| 龙里县| 郁南县| 沙雅县| 枣强县| 定襄县| 潜江市| 昭平县| 师宗县| 昭平县| 绍兴市| 墨江| 麻阳| 象山县| 礼泉县| 白朗县| 舞钢市| 杭锦后旗| 平果县| 绥滨县| 始兴县| 阿鲁科尔沁旗| 无棣县| 西乡县| 绥棱县| 凯里市| 汽车| 垦利县| 广西| 临安市| 孙吴县| 全椒县| 中阳县| 怀来县| 塔城市| 东港市| 旅游| 临汾市| 九龙城区|