如题所示,原本以为会是一个很简单的事情,真正上手处理后,发现有很多问题,网上的很多方案,都是部分解决,不够完善,所以写了一个工具类,有需要的,直接拿走
- 兼容assets多层嵌套文件夹的场景
- 增加拷贝成功的标识,万一copy中途失败的情况下,下次可以再次拷贝
package com.meitu.util
import android.content.res.AssetManager
import android.support.annotation.WorkerThread
import android.text.TextUtils
import com.meitu.library.application.BaseApplication
import java.io.*
/**
* 从assets复制内容到sd卡的工具类
* 1、增加复制成功的标识,便于判断复制中途失败的场景
* 2、兼容复制内容嵌套文件夹的场景
*/
class AssetsUtils {
companion object {
//复制成功的标记值,故意写一个无意义的单词,避免重复
val sCopySuccessMark = "copySuccessFile_falfjaee"
/**
* 从assets目录复制到素材中心在sd卡的目录下
*
* @param inputPath
* @return 是否成功处理
*/
@WorkerThread
fun copyFromAssetsToMaterialPath(inputPath: String, outputPath: String, maskSuccess: Boolean): Boolean {
var inputPath = inputPath
if (TextUtils.isEmpty(inputPath)) {
return false
}
if (inputPath.endsWith(File.separator)) {
inputPath = inputPath.substring(0, inputPath.length - 1)
}
//从assets复制
val assetManager = BaseApplication.getApplication().assets
val list: Array<String>?
try {
list = assetManager.list(inputPath)
} catch (e: IOException) {
return true
}
if (list == null || list.size == 0) {
if (maskSuccess) {
val file = File(outputPath, sCopySuccessMark)
file.parentFile.mkdirs()
file.createNewFile()
}
//如果有assets文件不存在,也当做成功,因为默认无效果也会当做素材来处理
return true
}
for (fileName in list) {
copyAssetsListFile(assetManager, inputPath, fileName, outputPath)
}
if (maskSuccess) {
val file = File(outputPath, sCopySuccessMark)
file.createNewFile()
}
return true
}
private fun copyAssetsListFile(assetManager: AssetManager, input: String, fileName: String, output: String) {
try {
val innerList = assetManager.list(input + File.separator + fileName)
if (innerList.isNullOrEmpty()) {
copySingleFile(assetManager, input, fileName, output)
} else {
for (innerFile in innerList) {
copyAssetsListFile(assetManager, input + File.separator + fileName, innerFile, output + File.separator + fileName)
}
}
} catch (e: IOException) {
e.printStackTrace()
}
}
private fun copySingleFile(assetManager: AssetManager, input: String, fileName: String, output: String): Boolean {
val outFile = File(output, fileName)
if (!outFile.parentFile.exists()) {
outFile.parentFile.mkdirs()
}
var inputStream: InputStream? = null
var out: OutputStream? = null
try {
inputStream = assetManager.open(input + File.separator + fileName)
out = FileOutputStream(outFile)
val buffer = ByteArray(1024)
var read: Int = inputStream!!.read(buffer)
while (read != -1) {
out.write(buffer, 0, read)
read = inputStream!!.read(buffer)
}
} catch (e: IOException) {
return false
} finally {
if (inputStream != null) {
try {
inputStream.close()
} catch (e: IOException) {
}
}
if (out != null) {
try {
out.flush()
out.close()
} catch (e: IOException) {
}
}
}
return true
}
}
}