Kotlin 协程Demo,实现预制脚本
2020-09-16 本文已影响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