Android 拷贝assets目录下所有文件及文件夹到指定路径

时间:2022-07-27 21:40:20

项目中需要将一些使用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();
		}
	}
}