Android:從assets拷貝文件夾到SD卡上

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

  • 兼容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
        }
    }

}
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1.內存管理 2.單例的理解 3.post和get的區別 4.md5和base64是什么,有什么區別 5.簡單談談...
    coder_Wg閱讀 1,303評論 1 6
  • 淺拷貝 copy.copy() copy函數是淺拷貝,只對可變類型的第一層對象進行拷貝,對拷貝的對象開辟新的內存空...
    越大大雨天閱讀 727評論 0 1
  • 引子 淺拷貝:指針拷貝,引用拷貝,指向同一內存地址 深拷貝:內容拷貝,指向不同內存地址,但是內容相同 容器類拷貝的...
    小白進城閱讀 1,605評論 1 9
  • iOS 可變拷貝VS不可變拷貝 概念 我們先來了解兩個概念 深拷貝deep copy: 直接拷貝整個對象內存到另一...
    wtqhy14615閱讀 724評論 1 0
  • 使用場景: 當我們涉及到拷貝時,通常使用的就是copy和mutableCopy這兩個方法。通常的使用場景是下面幾種...
    思也007閱讀 1,319評論 0 51