最近研發apk校驗服務,很多游戲安裝包兩三個G,如果整個拿去校驗,耗時基本二十多秒,這還僅僅是校驗的時間,如果加上下載的時間,等待時間太長了 網上很多方案嘗試了一下,不太行 1、fast md5 一個第三方庫,csdn有人用過說可以提升40%的速度,然後我去試了一下,本來9秒可以完成的校驗,變成了2 ...
最近研發apk校驗服務,很多游戲安裝包兩三個G,如果整個拿去校驗,耗時基本二十多秒,這還僅僅是校驗的時間,如果加上下載的時間,等待時間太長了
網上很多方案嘗試了一下,不太行
1、fast md5
一個第三方庫,csdn有人用過說可以提升40%的速度,然後我去試了一下,本來9秒可以完成的校驗,變成了2分多鐘,我真是口吐蓮花
2、把MD5替換成SHA演算法
提升不明顯,哪怕從30秒縮短到20幾秒,依然接受不了
所以只能尋求其它方案了
分片校驗法
很多上傳下載大文件,會採用分片的方法去做,這樣就可以開啟多個任務對同一個文件進行操作,速度提升好幾倍
如法炮製,先寫個demo嘗試一下,看看是否可行
先把文件進行分片,找個幾百M的apk測試一下
private fun verifySpilt() { filesDir?.let { path -> val it = File(path.absolutePath + "/test.apk") tvContent?.text = "${path.absolutePath}/test.apk" val inputStream = FileInputStream(it) var out: FileOutputStream? = null val inChannel = inputStream.channel var outChannel: FileChannel? = null val m = (10 * 1024 * 1024).toLong() // 分片數量 val count = (it.length() / m).toInt() Log.e("--==", "count $count") for (i in 0..count) { // 生成文件的路徑 val tPath = "${path.absolutePath}/test_$i" val toFile = File(tPath) if (toFile.exists()) { toFile.mkdir() } Log.e("--==", "to path $tPath") try { out = FileOutputStream(toFile) outChannel = out.channel // 從inChannel的m*i處,讀取固定長度的數據,寫入outChannel if (i != count) inChannel.transferTo( m * i, m, outChannel ) else { // 最後一個文件 inChannel.transferTo(m * i, it.length() - m * count, outChannel) } } catch (e: IOException) { Log.e("--==", "IOException $e") return } finally { out?.close() outChannel?.close() Log.e("--==", "finally close") } } inputStream.close() inChannel.close() } }
對 test.apk 進行分片校驗
直接在 demo 工程裡面 main方法調用
得到了十來個片段文件
接下來寫個校驗方法,對其中的片段文件校驗,比如分片後,刪了這些片段文件在重新生成,md5值是否一致
private fun verify(position: Int) { filesDir?.let { path -> val it = File(path.absolutePath + "/test1_$position") val digest = MessageDigest.getInstance("MD5") val fis = FileInputStream(it) val channel = fis.channel val byteBuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, it.length()) digest.update(byteBuffer) val bytes = digest.digest() tvContent?.text = bytes2HexString(bytes) Log.e("--==", "${bytes2HexString(bytes)}") } }
列印的日誌發現一致,說明只要切片的方式一樣,是可以進行校驗的
然後我改了分片的邏輯,每個片段大小調整了一下,得到5個片段,此時結果肯定就不一致了
其實到這裡已經算成型了,居然分片可行,那麼一個大文件直接分成10份,同時驗證,然後對比結果,速度可不止快了一倍
後面是無聊嘗試的結果,肯定是沒問題的,否則就要考慮代碼的問題了
找個視頻加一個新建的text文本,文本裡面輸入111,然後壓縮,得到 test1 的壓縮包
然後修改文本變成1111,在壓縮,得到 test2 壓縮包,在賦值 test1 壓縮包 得到 test1_copy 壓縮包,一共三個文件
把文件複製到記憶體目錄中測試
結果沒問題,畢竟是整個文件直接校驗