因爲assets和res下的文件都只能夠讀不能夠寫,那麼在程序初始化後,將後期須要使用而且須要修改的文件複製到SD卡。下面代碼提供一個工具類,將assets下的任意資源複製到SD卡下。
assets下的資源以下圖: java
下面是工具類:
AssetsCopyTOSDcard .javaandroid
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
在編程過程當中遇到的兩個問題:app
open failed: ENOENT (No such file or directory)
open failed: EISDIR (Is a directory)ide
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(); } }
修改成:this
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/48450487spa