如題所示,原本以為會是一個很簡單的事情,真正上手處理后,發現有很多問題,網上的很多方案,都是部分解決,不夠完善,所以寫了一個工具類,有需要的,直接拿走
- 兼容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
}
}
}