版權聲明:本文為HaiyuKing原創文章,轉載請注明出處!
前言
封裝了以下功能:
1、讀取assets目錄下的資源html、文件、圖片,將文件復制到SD卡目錄中;
2、讀取res/raw目錄下的文件內容;
3、讀寫./data/data/包名/下的文件;
效果圖

代碼分析
最常用的方法:getStringFromAssert(Context mContext, String assetsFilePath)【讀取assets目錄中的文件字符串】
使用步驟
一、項目組織結構圖

注意事項:
1、 導入類文件后需要change包名以及重新import R文件路徑
2、 Values目錄下的文件(strings.xml、dimens.xml、colors.xml等),如果項目中存在,則復制里面的內容,不要整個覆蓋
二、導入步驟
將AssetsUtils文件復制到項目中
package com.why.project.assetsutilsdemo.utils; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.webkit.WebView; import android.widget.Toast; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * @Create By HaiyuKing * @Used AssetsUtils【讀取assets、res/raw、./data/data/包名/目錄下的文件】 * <ui> * <li>1、讀取assets目錄下的資源html、文件、圖片;將文件復制到SD卡目錄中</li> * <li>2、讀取res/raw目錄下的文件內容</li> * <li>3、讀寫./data/data/包名/下的文件</li> * </ui> */ public class AssetsUtils { /** * 獲取assets的指定目錄中的所有文件及子目錄名數組 * @param assetsFolderPath - 目錄的相對路徑(目錄),例如:"why" * @注意 子目錄中必須有文件,否則不會將子目錄名稱寫入數組中 * @return [img,listdata.txt,test.html] * */ public static String[] getFileNamesArray(Context mContext, String assetsFolderPath){ String fileNames[] = null; try { fileNames = mContext.getResources().getAssets().list(assetsFolderPath);// 獲取assets目錄下的所有文件及子目錄名 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return fileNames; } /** * 使用webview加載assets目錄下的html網頁。比如想要打開assets/why/test.html * @param assetsFilePath - html文件的相對路徑,例如:"why/test.html"或者"test.html" * */ public static void loadAssetsHtml(WebView id_webview, String assetsFilePath) { id_webview.loadUrl("file:///android_asset/" + assetsFilePath); } /** * 訪問assets目錄下的資源文件,獲取文件中的字符串 * @param assetsFilePath - 文件的相對路徑,例如:"listitemdata.txt或者"/why/listdata.txt" * @return 內容字符串 * */ public static String getStringFromAssert(Context mContext, String assetsFilePath) { String content = ""; // 結果字符串 try { InputStream is = mContext.getResources().getAssets().open(assetsFilePath);// 打開文件 int ch = 0; ByteArrayOutputStream out = new ByteArrayOutputStream(); // 實現了一個輸出流 while ((ch = is.read()) != -1) { out.write(ch); // 將指定的字節寫入此 byte 數組輸出流 } byte[] buff = out.toByteArray();// 以 byte 數組的形式返回此輸出流的當前內容 out.close(); // 關閉流 is.close(); // 關閉流 content = new String(buff, "UTF-8"); // 設置字符串編碼 } catch (Exception e) { Toast.makeText(mContext, "對不起,沒有找到指定文件!", Toast.LENGTH_SHORT) .show(); } return content; } /** * 從assets目錄中復制整個文件夾內容到SD卡中 * @param mContext Context 使用CopyFiles類的Activity * @param assetsFolderPath String assets的相對路徑(目錄) 如:"why" * @param sdFolderPath String 復制到的sd路徑(目錄) 如:Environment.getExternalStorageDirectory() + "/why" */ public static void copyFolderFromAssetsToSD(Context mContext, String assetsFolderPath, String sdFolderPath) { try { String fileNames[] = mContext.getResources().getAssets().list(assetsFolderPath);// 獲取assets目錄下的所有文件及目錄名 if (fileNames.length > 0) {//如果是目錄,則新建目錄 File file = new File(sdFolderPath); if(! file.exists()){ file.mkdirs();//如果文件夾不存在,則創建目錄 } //遞歸,將目錄下的單個文件復制到目錄中 for (String fileName : fileNames) { copyFolderFromAssetsToSD(mContext, assetsFolderPath + "/" + fileName, sdFolderPath + "/" + fileName); } }else {//如果是文件 InputStream is = mContext.getResources().getAssets().open(assetsFolderPath); FileOutputStream fos = new FileOutputStream(new File(sdFolderPath)); byte[] buffer = new byte[1024]; int byteCount = 0; while ((byteCount = is.read(buffer)) != -1) {// 循環從輸入流讀取 // buffer字節 fos.write(buffer, 0, byteCount);// 將讀取的輸入流寫入到輸出流 } fos.flush();// 刷新緩沖區 is.close(); fos.close(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 從assets目錄中復制單個文件到SD卡中 * @param mContext Context 使用CopyFiles類的Activity * @param assetsFilePath String assets的相對路徑(目錄) 如:"why/img/image.png" * @param sdFilePath String 復制到的sd路徑(目錄) 如:Environment.getExternalStorageDirectory() + "/why/img.png" */ public static boolean copyOneFileFromAssetsToSD(Context mContext, String assetsFilePath, String sdFilePath) { try { InputStream stream = mContext.getResources().getAssets().open(assetsFilePath); File file = new File(sdFilePath); OutputStream o = null; try { //創建父目錄 String parentPath = file.getAbsolutePath(); String getFolderName = ""; if(parentPath == null || parentPath.length() == 0){ getFolderName = parentPath; }else{ int filePosi = parentPath.lastIndexOf(File.separator); getFolderName = (filePosi == -1) ? "" : parentPath.substring(0, filePosi); } Boolean makeDirs = false; if(getFolderName == null || getFolderName.length() == 0){ makeDirs = false; }else{ File folder = new File(getFolderName); makeDirs = (folder.exists() && folder.isDirectory()) ? true : folder.mkdirs(); } if(makeDirs){ o = new FileOutputStream(file,false); byte data[] = new byte[1024]; int length = -1; while ((length = stream.read(data)) != -1) { o.write(data, 0, length); } o.flush(); return true; } } catch (FileNotFoundException e) { throw new RuntimeException("FileNotFoundException occurred. ", e); } catch (IOException e) { throw new RuntimeException("IOException occurred. ", e); } finally { if (o != null) { try { o.close(); stream.close(); } catch (IOException e) { throw new RuntimeException("IOException occurred. ", e); } } } } catch (Exception e) { throw new RuntimeException("Exception occurred. ", e); } return false; } /** * 獲取assets目錄下的圖片資源的bitmap對象 * @param assetsImgPath - 文件的相對路徑,例如:image.png或者www/img/image.png * 使用方式:id_imageview.setImageBitmap(bitmap); * */ public static Bitmap getImageBitmapFromAssetsFile(Context mContext, String assetsImgPath) { Bitmap bitmap = null; try { InputStream is = mContext.getResources().getAssets().open(assetsImgPath); bitmap = BitmapFactory.decodeStream(is); is.close(); } catch (IOException e) { e.printStackTrace(); } return bitmap; } /** * 從res中的raw文件夾中獲取文件並讀取數據(資源文件只能讀不能寫) * @param rawFileId - 文件的ID值:R.raw.xxx;例如:R.raw.rawtext * @return 文件中的內容字符串 */ /* * 首先調用Context.getResource獲得當前應用程序上下文的Resources引用. * 然后調用openRawResource(int id)得到InputStream. * 最后,操作InputStream得到數據。 * 注意:把文件放在res/raw目錄下,則R類會自動提供該id.*/ public static String getStringFromRaw(Context mContext,int rawFileId) { String res = ""; try { InputStream in = mContext.getResources().openRawResource(rawFileId); int length = in.available(); byte[] buffer = new byte[length]; in.read(buffer); //res = EncodingUtils.getString(buffer, "GBK"); res = new String(buffer,"UTF-8"); in.close(); } catch (Exception e) { e.printStackTrace(); } return res; } /** * 寫入(./data/data/包名/file)文件里面內容 * * @param file - 私有文件夾下的文件名,例如:datatext.txt【在/data/data/{package}/目錄下】 * @param message - 想要寫入的數據字符串 */ public static void writeFileToData(Context mContext,String file, String message) { try { /* * MODE_APPEND 追加模式 - 如果已經存在的文件,將數據寫入到現有文件的末尾而不是抹去它。 * MODE_PRIVATE 私有模式 - 只有本程序或包名相同的程序才能訪問 * MODE_WORLD_READABLE 讀取模式 - 其他程序可以讀取此文件 * MODE_WORLD_WRITEABLE - 寫入模式 其他程序可以修改此文件 * 除了追加模式其他模式都會將內容全部覆蓋 */ FileOutputStream fout = mContext.openFileOutput(file, Context.MODE_PRIVATE); byte[] bytes = message.getBytes(); fout.write(bytes); fout.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 讀取./data/data/包名/file/下面的文件內容 * * @param fileName - 私有文件夾下的文件名,例如:datatext.txt * @return */ public static String getStringFileFromData(Context mContext,String fileName) { String res = ""; try { FileInputStream fin = mContext.openFileInput(fileName); int length = fin.available(); byte[] buffer = new byte[length]; fin.read(buffer); //res = EncodingUtils.getString(buffer, "UTF-8"); res = new String(buffer,"UTF-8"); fin.close(); } catch (Exception e) { e.printStackTrace(); } return res; } }
在AndroidManifest.xml中添加權限
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.why.project.assetsutilsdemo"> <!-- ======================AssetsUtils【讀取assets、res/raw、./data/data/包名/目錄下的文件】====================== --> <!-- 在SD卡中創建與刪除文件權限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <!-- 向SD卡寫入數據權限 --> <uses-permission android:name="android.permission.REORDER_TASKS"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
添加運行時權限的處理(本demo中采用的是修改targetSDKVersion=22)
三、使用方法
獲取assets的指定目錄中的所有文件及子目錄名數組
btn_getFileNamesArray.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //獲取assets的指定目錄中的所有文件及子目錄名數組 String[] assetsWwwFilesNameArray = AssetsUtils.getFileNamesArray(MainActivity.this,"why"); String filesName = "--why\n"; for(int i=0;i<assetsWwwFilesNameArray.length;i++){ filesName += " --" + assetsWwwFilesNameArray[i] + "\n"; } //顯示 hiddenAll(); id_text.setVisibility(View.VISIBLE); id_text.setText(filesName); } });

使用webview加載assets目錄下的html網頁
loadAssetsHtml.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //使用webview加載assets目錄下的html網頁 AssetsUtils.loadAssetsHtml(id_web,"why/test.html"); //顯示 hiddenAll(); id_web.setVisibility(View.VISIBLE); } });

訪問assets目錄下的資源文件,獲取文件中的字符串
getStringFromAssert.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //訪問assets目錄下的資源文件,獲取文件中的字符串 String listdata = AssetsUtils.getStringFromAssert(MainActivity.this,"listitemdata.txt"); //顯示 hiddenAll(); id_text.setVisibility(View.VISIBLE); id_text.setText(listdata); } });

從assets目錄中復制整個文件夾內容到SD卡中
copyFolderFromAssetsToSD.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //從assets目錄中復制整個文件夾內容到SD卡中 String sdFolderPath = Environment.getExternalStorageDirectory() + "/why"; AssetsUtils.copyFolderFromAssetsToSD(MainActivity.this, "why", sdFolderPath); } });

從assets目錄中復制單個文件到SD卡中
copyOneFileFromAssetsToSD.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //從assets目錄中復制單個文件到SD卡中 String sdFilePath = Environment.getExternalStorageDirectory() + "/why/listitemdata.txt"; AssetsUtils.copyOneFileFromAssetsToSD(MainActivity.this,"listitemdata.txt",sdFilePath); } });

獲取assets目錄下的圖片資源的bitmap對象
getImageBitmapFromAssetsFile.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //獲取assets目錄下的圖片資源的bitmap對象 Bitmap bitmap = AssetsUtils.getImageBitmapFromAssetsFile(MainActivity.this, "why/img/image.png"); //顯示 hiddenAll(); id_img.setVisibility(View.VISIBLE); id_img.setImageBitmap(bitmap); } });

從res中的raw文件夾中獲取文件並讀取數據(資源文件只能讀不能寫)
getStringFromRaw.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //從res中的raw文件夾中獲取文件並讀取數據(資源文件只能讀不能寫) String rawFileStr = AssetsUtils.getStringFromRaw(MainActivity.this, R.raw.rawtext); //顯示 hiddenAll(); id_text.setVisibility(View.VISIBLE); id_text.setText(rawFileStr); } });

寫入(./data/data/包名/file)文件里面內容
writeFileToData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //寫入(./data/data/包名/file)文件里面內容 AssetsUtils.writeFileToData(MainActivity.this, "datatext.txt", "這是寫入./data/data/包名/下的文件的內容"); } });
讀取./data/data/包名/file/下面的文件內容
getStringFileFromData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //讀取./data/data/包名/file/下面的文件內容 String dataFileStr = AssetsUtils.getStringFileFromData(MainActivity.this, "datatext.txt"); //顯示 hiddenAll(); id_text.setVisibility(View.VISIBLE); id_text.setText(dataFileStr); } });

混淆配置
無
參考資料
暫時空缺
