AssetsUtils【讀取assets、res/raw、./data/data/包名/目錄下的文件】


版權聲明:本文為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;
    }
    
}
AssetsUtils.java

在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);
            }
        });

 

混淆配置

參考資料

暫時空缺

項目demo下載地址

 https://github.com/haiyuKing/AssetsUtilsDemo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM