srcRelPath 为源文件相对于 assets 的相对路径,dstAbsPath 为目标文件的绝对路径。
当目标文件已经存在时,若 forceCopy 为 true,则覆盖;否则跳过。
import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class AssetHelper {
private static final String TAG = AssetHelper.class.getSimpleName();
private AssetHelper() {
}
public static byte[] getAssetFileData(Context context, String fileName) {
try (InputStream in = context.getResources().getAssets()
.open(fileName, AssetManager.ACCESS_STREAMING)) {
final int size = in.available();
byte[] data = new byte[size];
in.read(data, 0, size);
return data;
} catch (IOException e) {
Log.e(TAG, "getAssetFileData: " + e);
return null;
}
}
public static boolean copyAssetFiles(Context context, String assetRelPath, String dstAbsPath,
boolean forceCopy) {
AssetManager assets = context.getResources().getAssets();
return copyAssetFiles(assets, assetRelPath, dstAbsPath, forceCopy);
}
private static boolean copyAssetFiles(AssetManager assets, String srcRelPath, String dstAbsPath,
boolean forceCopy) {
String[] subFiles;
try {
subFiles = assets.list(srcRelPath);
} catch (IOException e) {
Log.e(TAG, "copyAssetFiles: " + e);
return false;
}
if (subFiles.length == 0) {
return copyAssetFile(assets, srcRelPath, dstAbsPath, forceCopy);
} else {
File dstDir = new File(dstAbsPath);
if (!dstDir.isDirectory()) {
if (!deleteFileOrDir(dstDir)) {
Log.e(TAG, "copyAssetFiles: Can not delete " + dstDir.getAbsolutePath());
return false;
}
if (!dstDir.mkdirs()) {
Log.e(TAG, "copyAssetFiles: Can not create " + dstDir.getAbsolutePath());
return false;
}
}
boolean result = true;
for (String subFile : subFiles) {
result &= copyAssetFiles(assets, srcRelPath + File.separator + subFile,
dstAbsPath + File.separator + subFile, forceCopy);
}
return result;
}
}
private static boolean copyAssetFile(AssetManager assets, String srcRelPath, String dstAbsPath,
boolean forceCopy) {
File file = new File(dstAbsPath);
if (file.isFile() && !forceCopy) {
return true;
}
if (!deleteFileOrDir(file)) {
Log.e(TAG, "copyAssetFile: Can not delete " + file.getAbsolutePath());
return false;
}
try (InputStream is = assets.open(srcRelPath, AssetManager.ACCESS_STREAMING);
DataInputStream dis = new DataInputStream(is);
FileOutputStream fos = new FileOutputStream(file);
DataOutputStream dos = new DataOutputStream(fos);) {
final int size = 1024;
byte[] buffer = new byte[size];
int len = 0;
while ((len = dis.read(buffer, 0, size)) != -1) {
dos.write(buffer, 0, len);
dos.flush();
}
return true;
} catch (IOException e) {
Log.e(TAG, "copyAssetFile: " + e);
return false;
}
}
public static boolean deleteFileOrDir(File file) {
if (!file.exists()) {
return true;
}
if (file.isFile()) {
return file.delete();
}
// file.isDirectory()
File[] subFiles = file.listFiles();
boolean subDeleted = true;
if (subFiles != null) {
for (File subFile : subFiles) {
subDeleted &= deleteFileOrDir(subFile);
}
}
return subDeleted ? file.delete() : false;
}
}