版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pbm863521/article/details/78811250
项目中需要把一些模型文件打包到apk中,安装的时候释放到手机中,APP启动时调用。
Android除了提供/res目录存放资源文件外,在/assets目录也会提供存放资源文件,且assets 目录中的文件,会不经压缩打包至APK包中。在/res下是可编译的资源文件, 这种资源文件系统会在R.java里面自动生成该资源文件的ID,访问也很简单,只需要调用R.XXX.id即可;在/assets目录下面不会在R.java里面自动生成ID,所以读取assets目录下面的资源文件需要提供路径,我们可以通过AssetManager类来访问这些文件。
AssetManager提供了如下方法用于处理assets:
String[] list(String path);//列出该目录下的下级文件和文件夹名称
InputStream open(String fileName);//以顺序读取模式打开文件,默认模式为ACCESS_STREAMING
InputStream open(String fileName, int accessMode);//以指定模式打开文件。读取模式有以下几种:
//ACCESS_UNKNOWN : 未指定具体的读取模式
//ACCESS_RANDOM : 随机读取
//ACCESS_STREAMING : 顺序读取
//ACCESS_BUFFER : 缓存读取
void close()//关闭AssetManager实例
实现代码:
/assets目录下的文件:
/**
* 从assets目录中复制整个文件夹内容,考贝到 /data/data/包名/files/目录中
* @param activity activity 使用CopyFiles类的Activity
* @param filePath String 文件路径,如:/assets/aa
*/
public static void copyAssetsDir2Phone(Activity activity, String filePath){
try {
String[] fileList = activity.getAssets().list(filePath);
if(fileList.length>0) {//如果是目录
File file=new File(activity.getFilesDir().getAbsolutePath()+ File.separator+filePath);
file.mkdirs();//如果文件夹不存在,则递归
for (String fileName:fileList){
filePath=filePath+File.separator+fileName;
copyAssetsDir2Phone(activity,filePath);
filePath=filePath.substring(0,filePath.lastIndexOf(File.separator));
Log.e("oldPath",filePath);
}
} else {//如果是文件
InputStream inputStream=activity.getAssets().open(filePath);
File file=new File(activity.getFilesDir().getAbsolutePath()+ File.separator+filePath);
Log.i("copyAssets2Phone","file:"+file);
if(!file.exists() || file.length()==0) {
FileOutputStream fos=new FileOutputStream(file);
int len=-1;
byte[] buffer=new byte[1024];
while ((len=inputStream.read(buffer))!=-1){
fos.write(buffer,0,len);
}
fos.flush();
inputStream.close();
fos.close();
showToast(activity,"模型文件复制完毕");
} else {
showToast(activity,"模型文件已存在,无需复制");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 将文件从assets目录,考贝到 /data/data/包名/files/ 目录中。assets 目录中的文件,会不经压缩打包至APK包中,使用时还应从apk包中导出来
* @param fileName 文件名,如aaa.txt
*/
public static void copyAssetsFile2Phone(Activity activity, String fileName){
try {
InputStream inputStream = activity.getAssets().open(fileName);
//getFilesDir() 获得当前APP的安装路径 /data/data/包名/files 目录
File file = new File(activity.getFilesDir().getAbsolutePath() + File.separator + fileName);
if(!file.exists() || file.length()==0) {
FileOutputStream fos =new FileOutputStream(file);//如果文件不存在,FileOutputStream会自动创建文件
int len=-1;
byte[] buffer = new byte[1024];
while ((len=inputStream.read(buffer))!=-1){
fos.write(buffer,0,len);
}
fos.flush();//刷新缓存区
inputStream.close();
fos.close();
showToast(activity,"模型文件复制完毕");
} else {
showToast(activity,"模型文件已存在,无需复制");
}
} catch (IOException e) {
e.printStackTrace();
}
}
copyAssetsDir2Phone复制文件夹,copyAssetsFile2Phone复制某个文件,getFilesDir() 获得当前APP的安装路径 /data/data/包名/files 目录。
调用方法:
runOnUiThread(new Runnable() {
@Override
public void run() {
copyAssetsDir2Phone(MainActivity.this,"face");
}
});
final String configPath = getFilesDir().getAbsolutePath() + "/face/configure";
经测试,文件拷贝成功。
扫描二维码关注公众号,回复:
3878630 查看本文章
参考文章:
http://mobile.51cto.com/aprogram-387591.htm
http://blog.csdn.net/yunliupan/article/details/17116605
http://blog.csdn.net/etzmico/article/details/7786525/