既然是要对assets资源目录操作。首先来解释下assets是啥?
Android 中资源分为两种,
①、第一种是res下可编译的资源文件,这种资源文件系统会在R.java里面自动生成该资源文件的ID,(除了raw外,其他资源目录中的资源文件都会被编译),这也是为什么将APK文件解压后无法直接查看XML格式资源文件内容的原因。而assets与res/raw目录中的资源文件不会做任何处理,所以将APK解压后,这两个目录中的资源文件都会保持原样。res目录只能有一层子目录,而且这些子目录必须是预定义的,如res/layout、res/values等都是合法的,而res/abc,res/xyz并不是合法的资源目录。
②、第二种就是放在assets文件夹下面的原生资源文件,放在这个文件夹下面的文件不会被R文件编译,所以不能像第一种那样直接使用.Android提供了一个工具类,方便我们操作获取assets文件下的文件,在assets目录中可以建任意层次的子目录(只受操作系统的限制)。
接下来来点对assets实际的操作:
一、读取assets下的txt文件内容。
二、复制assets下文件夹中的文件到手机的其它(新建或者已有文件夹)路径中。
下面秀操作了(开始装逼-哈哈):
一、读取assets下的txt文件内容:(写成工具类,这样调用起来就方便了)
//读取本地JSON字符
public static String ReadDayDayString(Context context) {
InputStream is = null;
String msg = null;
try {
is = context.getResources().getAssets().open("mprespons.txt");
byte[] bytes = new byte[is.available()];
is.read(bytes);
msg = new String(bytes);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return msg;
}
上面代码中主要说下context.getResources().getAssets().open("xxx.txt");它是读取assets下对应的文件方法open()方法里面传对应打开的文件全名;
其它就是很简单的Java-IO流的操作。非常简单。
二、复制assets下文件夹中的文件(同样写成工具类):
首先我们要复制assets下文件夹中的文件用上面的open("xxx.txt")方法肯定是不行了,你会想我用open("test\xx.txt")行不行。那你就想的太简单了。事实告诉我们当然不行抛出了IOException异常。不过好在Android 给了我们其他可执行的方法;
String[]listFiles=context.getAssets().list(rootDirFullPath);// 遍历该目录下的文件和文件夹名
rootDirFullPath传的是空字符串("")时获取assets下全部文件或文件夹名 可以看到返回了一个字符串数组。这样我们就可以下一步操作了
public class Util {
/**
* 从assets目录下拷贝整个文件夹,不管是文件夹还是文件都能拷贝
*
* @param context 上下文
* @param rootDirFullPath 文件目录,要拷贝的目录如assets目录下有一个tessdata文件夹:
* @param targetDirFullPath 目标文件夹位置如:/Download/tessdata
*/
public static void copyFolderFromAssets(Context context, String rootDirFullPath, String targetDirFullPath) {
Log.d("Tag", "copyFolderFromAssets " + "rootDirFullPath-" + rootDirFullPath + " targetDirFullPath-" + targetDirFullPath);
try {
String[] listFiles = context.getAssets().list(rootDirFullPath);// 遍历该目录下的文件和文件夹
for (String string : listFiles) {// 判断目录是文件还是文件夹,这里只好用.做区分了
Log.d("Tag", "name-" + rootDirFullPath + "/" + string);
if (isFileByName(string)) {// 文件
copyFileFromAssets(context, rootDirFullPath + "/" + string, targetDirFullPath + "/" + string);
} else {// 文件夹
String childRootDirFullPath = rootDirFullPath + "/" + string;
String childTargetDirFullPath = targetDirFullPath + "/" + string;
new File(childTargetDirFullPath).mkdirs();
copyFolderFromAssets(context, childRootDirFullPath, childTargetDirFullPath);
}
}
} catch (IOException e) {
Log.d("Tag", "copyFolderFromAssets " + "IOException-" + e.getMessage());
Log.d("Tag", "copyFolderFromAssets " + "IOException-" + e.getLocalizedMessage());
e.printStackTrace();
}
}
private static boolean isFileByName(String string) {
if (string.contains(".")) {
return true;
}
return false;
}
/**
* 从assets目录下拷贝文件
*
* @param context 上下文
* @param assetsFilePath 文件的路径名如:SBClock/0001cuteowl/cuteowl_dot.png
* @param targetFileFullPath 目标文件路径如:/sdcard/SBClock/0001cuteowl/cuteowl_dot.png
*/
public static void copyFileFromAssets(Context context, String assetsFilePath, String targetFileFullPath) {
Log.d("Tag", "copyFileFromAssets ");
InputStream assestsFileImputStream;
try {
assestsFileImputStream = context.getAssets().open(assetsFilePath);
copyFile(assestsFileImputStream, targetFileFullPath);
} catch (IOException e) {
Log.d("Tag", "copyFileFromAssets " + "IOException-" + e.getMessage());
e.printStackTrace();
}
}
private static void copyFile(InputStream in, String targetPath) {
try {
FileOutputStream fos = new FileOutputStream(new File(targetPath));
byte[] buffer = new byte[1024];
int byteCount = 0;
while ((byteCount = in.read(buffer)) != -1) {// 循环从输入流读取
// buffer字节
fos.write(buffer, 0, byteCount);// 将读取的输入流写入到输出流
}
fos.flush();// 刷新缓冲区
in.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
当然我们在使用前可以加上一点判断是否已经复制存在过:
private void initAssets() {
new Thread(new Runnable() {
@Override
public void run() {
Log.e("Tag", "执行");
File file = new File(File_Path);
if (!file.exists()) {
Log.e("Tag", "创建文件夹");
file.mkdirs();
}
if (TextUtils.isEmpty(App.getSP().getString("iscopy"))) {
Log.e("Tag", "复制文件");
Util.copyFolderFromAssets(MainActivity.this, "tessdata", File_Path);
App.getSP().put("iscopy", "true");
}
}
}).start();
}
来点git图 项目结构图: 复制assets下tessdata文件夹中的两个文件到Download下新建的tessdata文件夹中
好了,小弟功力有限,希望对你有那么一丢丢用。欢迎提出各种问题和指点。
最后附上小弟的github地址:github地址