由于assets和res下的文件都只可以读不可以写,那么在程序初始化后,将后期需要使用并且需要修改的文件复制到SD卡。下面代码提供一个工具类,将assets下的任意资源复制到SD卡下。
assets下的资源如下图:
下面是工具类:
AssetsCopyTOSDcard .java
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream; import android.content.Context;
import android.content.res.AssetManager;
import android.os.Environment; public class AssetsCopyTOSDcard {
Context context; public AssetsCopyTOSDcard(Context context) {
super();
this.context = context;
} /**
* @param context
* @param assetpath asset下的路径
* @param SDpath SDpath下保存路径
*/
public void AssetToSD(String assetpath,String SDpath ){ AssetManager asset=context.getAssets();
//循环的读取asset下的文件,并且写入到SD卡
String[] filenames=null;
FileOutputStream out = null;
InputStream in=null;
try {
filenames = asset.list(assetpath);
if(filenames.length>0){//说明是目录
//创建目录
getDirectory(assetpath); for(String fileName:filenames){
AssetToSD(assetpath+"/"+fileName, SDpath+"/"+fileName);
}
}else{//说明是文件,直接复制到SD卡
File SDFlie=new File(SDpath);
String path=assetpath.substring(0, assetpath.lastIndexOf("/"));
getDirectory(path); if(!SDFlie.exists()){
SDFlie.createNewFile();
}
//将内容写入到文件中
in=asset.open(assetpath);
out= new FileOutputStream(SDFlie);
byte[] buffer = new byte[1024];
int byteCount=0;
while((byteCount=in.read(buffer))!=-1){
out.write(buffer, 0, byteCount);
}
out.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
out.close();
in.close();
asset.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}
//分级建立文件夹
public void getDirectory(String path){
//对SDpath进行处理,分层级建立文件夹
String[] s=path.split("/");
String str=Environment.getExternalStorageDirectory().toString();
for (int i = 0; i < s.length; i++) {
str=str+"/"+s[i];
File file=new File(str);
if(!file.exists()){
file.mkdir();
}
} }
}
MainActivity .java
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.view.Menu; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String path="aaa/a1.txt";
AssetsCopyTOSDcard assetsCopyTOSDcard=new AssetsCopyTOSDcard(getApplicationContext());
assetsCopyTOSDcard.AssetToSD(path,Environment.getExternalStorageDirectory().toString()+"/"+path);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
测试路径:
aaa
Aaa/bbb
Aaa/bbb/ba.txt
Aaa/a1.txt
在编程过程中遇到的两个问题:
open failed: ENOENT (No such file or directory)
open failed: EISDIR (Is a directory)
错误修改
if(!SDFlie.exists()){
SDFlie.createNewFile();
}
//将内容写入到文件中
in=asset.open(assetpath);
out= new FileOutputStream(SDFlie);
byte[] buffer = new byte[1024];
int byteCount=0;
while((byteCount=in.read(buffer))!=-1){
out.write(buffer, 0, byteCount);
}
out.flush();
修改为:
if(!SDFlie.exists()){
SDFlie.createNewFile();
//将内容写入到文件中
in=asset.open(assetpath);
out= new FileOutputStream(SDFlie);
byte[] buffer = new byte[1024];
int byteCount=0;
while((byteCount=in.read(buffer))!=-1){
out.write(buffer, 0, byteCount);
}
} out.flush();
因为当文件存在时,不复制。不修改的情况下,out.close();会报空指针异常。
finally{
try {
out.close();
in.close();
asset.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
修改为:
finally{
try {
if(out!=null){
out.close();
out=null;
}
if(in!=null){
in.close();
in=null;
}
/**
* 关闭报错,java.lang.RuntimeException:
* Unable to start activity ComponentInfo
* {com.example.wealth/com.example.wealth.UI.main}:
* java.lang.RuntimeException: Assetmanager has been closed
*/
// if(asset!=null){
// asset.close();
// asset=null;
// }
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
转: https://blog.csdn.net/qq_17326933/article/details/48450487