美文网首页
Kotlin 协程Demo,实现预制脚本

Kotlin 协程Demo,实现预制脚本

作者: 贼噶人 | 来源:发表于2020-09-16 10:39 被阅读0次

使用Kotlin 实现多协程同时下载文件,充分利用IO

image.png
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONArray
import com.alibaba.fastjson.JSONObject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.runBlocking
import okhttp3.FormBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okio.*
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream
import java.util.*
import java.util.zip.ZipFile
import kotlin.collections.HashMap
import kotlin.collections.HashSet

/**
* 模拟登录
*/
fun login() : Flow<JSONObject>{
   return flow {
       val form = FormBody.Builder()
       form.add("user.phone", "18507051259")
       form.add("user.password", "123456")
       form.add("deviceType", "android")
       form.add("app_pkg_name", "com.mytian.appstore.rz")
       form.add("app_channel", "mytian")
       form.add("client_version", "82")
       emit(
           JSON.parseObject(
               OkHttpClient().newCall(
                   Request
                       .Builder().url("http://www.dsadsdsad.com.cn/dasds/userAction_login.do")
                       .post(form.build()).build()
               ).execute().body?.string()
           )
       )
   }
}

fun loadListInfo(uid: String, token: String, classType: String) : Flow<JSONObject>{
   return flow {
       listOf("100","101","102","103","104","105","106","111","119","117","601","701").forEach {
           val form = FormBody.Builder()
           form.add("uid", uid)
           form.add("token", token)
           form.add("typeId", it)
           form.add("deviceType", "android")
           form.add("deviceTypes", "android")
           form.add("app_pkg_name", "com.mytian.appstore.rz")
           form.add("appNames", "com.mytian.appstore.rz")
           form.add("app_channel", "mytian")
           form.add("client_version", "125")
           form.add("versions", "125")
           form.add("channels", "mytian")
           form.add("clazzRecord", "[]")
           form.add("currentPage", "1")
           form.add("pageSize", "156")
           emit(
               JSON.parseObject(
                   OkHttpClient().newCall(
                       Request
                           .Builder().url("https://cloud.dsdas.com:7776/clazz/getClassList")
                           .post(form.build()).build()
                   ).execute().body?.string()
               )
           )
       }
   }
}

fun downloadRes(downloadUrl:String,id:String) {
   println("download begin $id")
   OkHttpClient().newCall(Request.Builder().get().url(downloadUrl).build())
       .execute().also {
           if (it.isSuccessful) {
               var sink = File("D:\\cocos2d"+File.separator+id +".zip")
                   .sink().buffer()
               it.body?.source()?.readAll(sink)
               sink.flush()
               it.body?.close()
               sink.close()
               println("download end $id")
           }
       }
}

fun downloadPre(info: JSONObject,infoMap:HashMap<String,String>) {
   downloadRes(info["resUrl"].toString(), info["pkgName"].toString())
   var gzipOut = ByteArrayOutputStream()
   gzipOut.sink().gzip().buffer().write(JSON.toJSONBytes(info)).flush()
   var gzipInfo = Base64.getEncoder().encodeToString(gzipOut.toByteArray())
   infoMap[info["pkgName"].toString()] = gzipInfo
   println("$gzipInfo")
   gzipOut.close()
}

fun unZip(zipFile: File, targetDir: File) {
   runBlocking {
       targetDir.apply {
           if (!exists()) {
               mkdirs()
           }
       }
       ZipFile(zipFile).also {zip ->
           zip.entries().run {
               while (hasMoreElements()) {
                   nextElement().also { entry->
                       if (entry.isDirectory) {
                           File("${targetDir.absoluteFile}${File.separator}${entry.name}").run {
                               if (!exists()) {
                                   mkdirs()
                               }
                           }
                       } else {
                           async(Dispatchers.IO) {
                               var sink =
                                   File("${targetDir.absoluteFile}${File.separator}${entry.name}").sink().buffer()
                               var source =
                                   zip.getInputStream(entry).source().buffer()
                               source.readAll(sink)
                               sink.flush()
                               source.close()
                               sink.close()
                           }
                       }
                   }
               }
           }
       }
   }
}

fun main(args: Array<String>) {
   var begin = System.currentTimeMillis()
   runBlocking {
       File("D:\\cocos2d${File.separator}").listFiles().forEach {
           if (it.absolutePath.endsWith(".zip")) {
               println(it)
               async (Dispatchers.IO){
                   unZip(
                       it,
                       File(it.absolutePath.replace(".zip", ""))
                   )
               }
           }
       }
   }
   println(System.currentTimeMillis() - begin)


   var infoMap:HashMap<String,String> = HashMap()
   var commonDownloadM:HashSet<String> = HashSet();
   runBlocking {
       async(Dispatchers.IO) {
           login().collect {
               loadListInfo(
                   (it["info"] as JSONObject)["uid"].toString(), (it["info"] as JSONObject)["token"].toString()
               ,"100").collect {
                   async (Dispatchers.IO){
                       async(Dispatchers.IO) {
                           var commonList = ((it["info"] as JSONObject)["commonList"] as JSONArray)
                           if (commonList.size > 0) {
                               synchronized(commonDownloadM) {
                                   if (!commonDownloadM.contains((commonList[0] as JSONObject)["pkgName"])) {
                                       commonDownloadM.add((commonList[0] as JSONObject)["pkgName"] as String)
                                       async(Dispatchers.IO) {
                                           downloadPre(commonList[0] as JSONObject, infoMap)
                                       }
                                   }
                                   if (commonList.size > 1) {
                                       if (!commonDownloadM.contains((commonList[1] as JSONObject)["pkgName"])) {
                                           commonDownloadM.add((commonList[1] as JSONObject)["pkgName"] as String)
                                           async(Dispatchers.IO) {
                                               downloadPre(commonList[1] as JSONObject, infoMap)
                                           }
                                       }
                                   }
                               }
                           }
                           downloadPre(((it["info"] as JSONObject)["classList"] as JSONArray)[0] as JSONObject,infoMap)
                       }
                   }
               }
           }
       }
   }
   println(infoMap)
   var dirMap = HashMap<String, HashSet<String>>()
   dirMap["Rz"] = HashSet<String>().also {
       it.add("com.mytian.l00lz001")
       it.add("com.mytian.common.ph")
       it.add("com.mytian.common")
   }
   dirMap["En"] = HashSet<String>().also {
       it.add("com.mytian.l00ne001")
       it.add("com.mytian.common.ph")
       it.add("com.mytian.common")
   }
   dirMap["Ma"] = HashSet<String>().also {
       it.add("com.mytian.l00ma001")
       it.add("com.mytian.common.ph")
       it.add("com.mytian.common")
   }
   dirMap["Lo"] = HashSet<String>().also {
       it.add("com.mytian.l00lo001")
       it.add("com.mytian.common.ph")
       it.add("com.mytian.common")
   }
   dirMap["Xz"] = HashSet<String>().also {
       it.add("com.mytian.l00xz001")
       it.add("com.mytian.common.ph")
       it.add("com.mytian.common")
   }
   dirMap["Ph"] = HashSet<String>().also {
       it.add("com.mytian.l00ph001")
       it.add("com.mytian.common.ph")
       it.add("com.mytian.common")
   }
   dirMap["Py"] = HashSet<String>().also {
       it.add("com.mytian.l00py001")
       it.add("com.mytian.common.ph")
       it.add("com.mytian.common")
   }
   runBlocking {
       dirMap.forEach { (t, u) ->
           async (Dispatchers.IO){
               File("D:\\cocos2d${File.separator}${t}").apply {
                   if (exists() || mkdirs()) {
                       var properties = Properties()
                       u.forEach { item ->
                           var source = File("D:\\cocos2d${File.separator}$item.zip").source().buffer()
                           var sink = File(
                               "D:\\cocos2d${File.separator}${t}${File.separator}${
                                   if ("com.mytian.common.ph" == item) "commonUnity" else item.split(".").last()
                               }.zip"
                           ).sink().buffer()
                           source.readAll(sink)
                           source.close()
                           sink.flush()
                           sink.close()
                           properties[if ("com.mytian.common.ph" == item) "commonUnity" else item.split(".").last()] =
                               infoMap[item]
                       }
                       var outputStream = FileOutputStream( File("D:\\cocos2d${File.separator}${t}${File.separator}info.xml"))
                       properties.storeToXML(outputStream,null)
                       outputStream.flush()
                       outputStream.close()
                   }
               }
           }
       }
   }
}


Kotllin协程解压文件 14个文件 解压耗时1412ms

image.png
image.png

相关文章

网友评论

      本文标题:Kotlin 协程Demo,实现预制脚本

      本文链接:https://www.haomeiwen.com/subject/asecyktx.html