1. 程式人生 > >Android 拷貝assets目錄下所有檔案及資料夾到指定路徑

Android 拷貝assets目錄下所有檔案及資料夾到指定路徑

專案中需要將一些使用NDK編譯的so庫檔案放到assets目錄打包。因為所有so檔案是按照目錄存放和查詢載入的,libs路徑打包有問題,就考慮放到assets下,啟動的時候進行拷貝。從網路上找到一個拷貝的類,做了些小的修改,以滿足拷貝所有檔案及資料夾的需求。

/*******************************************************************************************
*
*FileName:	AssetsCopyer.java
*Author:	xxx
*Time:		2016年6月28日 下午3:31:49
*
/******************************************************************************************/
package com.xxx.vr.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.content.Context;
import android.content.res.AssetManager;
import android.text.TextUtils;
import android.util.Log;

public class AssetsCopyer {

	private static final String TAG = "AssetsCopyer";
	
	public static void releaseAssets(Context context, String assetsDir,
            String releaseDir) {
		
//		Log.d(TAG, "context: " + context + ", " + assetsDir);
        if (TextUtils.isEmpty(releaseDir)) {
            return;
        } else if (releaseDir.endsWith("/")) {
            releaseDir = releaseDir.substring(0, releaseDir.length() - 1);
        }
 
        if (TextUtils.isEmpty(assetsDir) || assetsDir.equals("/")) {
            assetsDir = "";
        } else if (assetsDir.endsWith("/")) {
            assetsDir = assetsDir.substring(0, assetsDir.length() - 1);
        }
 
        AssetManager assets = context.getAssets();
        try {
            String[] fileNames = assets.list(assetsDir);//只能獲取到檔案(夾)名,所以還得判斷是資料夾還是檔案
            if (fileNames.length > 0) {// is dir
                for (String name : fileNames) {
                    if (!TextUtils.isEmpty(assetsDir)) {
                        name = assetsDir + File.separator + name;//補全assets資源路徑
                    }
//                    Log.i(, brian name= + name);
                    String[] childNames = assets.list(name);//判斷是檔案還是資料夾
                    if (!TextUtils.isEmpty(name) && childNames.length > 0) {
                    	checkFolderExists(releaseDir + File.separator + name);
                        releaseAssets(context, name, releaseDir);//遞迴, 因為資源都是帶著全路徑, 
                                                                                           //所以不需要在遞迴是設定目標資料夾的路徑
                    } else {
                        InputStream is = assets.open(name);
//                        FileUtil.writeFile(releaseDir + File.separator + name, is);
                        writeFile(releaseDir + File.separator + name, is);
                    }
                }
            } else {// is file
                InputStream is = assets.open(assetsDir);
                // 寫入檔案前, 需要提前級聯建立好路徑, 下面有程式碼貼出
//                FileUtil.writeFile(releaseDir + File.separator + assetsDir, is);
                writeFile(releaseDir + File.separator + assetsDir, is);
            }
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
	
	private static boolean writeFile(String fileName, InputStream in) throws IOException
	{
		boolean bRet = true;
		try {
			OutputStream os = new FileOutputStream(fileName);
			byte[] buffer = new byte[4112];
			int read;
			while((read = in.read(buffer)) != -1)
			{
				os.write(buffer, 0, read);
			}
			in.close();
			in = null;
			os.flush();
			os.close();
			os = null;
//			Log.v(TAG, "copyed file: " + fileName);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			bRet = false;
		}
		return bRet;
	}
	
	private static void checkFolderExists(String path)
	{
		File file = new File(path);
		if((file.exists() && !file.isDirectory()) || !file.exists())
		{
			file.mkdirs();
		}
	}
}