Android中的文件讀寫操作

在android開發中文件操作使用的其實還是比較高頻的,之前我遇到這種需求都隨便寫寫,對此沒有一個比較全面的認識,所以想借這篇文章來梳理一遍。

由於需要讀寫文件,這包含了讀寫外部sd card的文件,所以需要添加對飲的讀寫權限

<!-- SDCard中創建與刪除文件權限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

<!--讀取SDCard數據權限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<!-- 向SDCard寫入數據權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

1、獲取存儲路徑

android可能有兩個地方可以存儲文件,一是存放在sd卡中(如果有的話),另外就是存儲在內存卡中,那麼與此對應的就有兩組方法來獲取存儲路徑。

a、獲取sd卡相關路徑的方法

關於獲取sd卡相關路徑方法和獲取到的路徑的對應關係如下

Environment.getExternalStorageDirectory().getAbsolutePath()

/storage/emulated/0
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath())

/storage/emulated/0/DCIM

這兩個方法是通過Environment提供的方法來獲取sd卡路徑,可以看到的獲取的基本是sd卡的根路徑,而實際上/storage/emulated/0這個路徑代表是的第一行sd卡,當我們在該路徑下創建yoryky.txt文件時,實際手機上看到的路徑是/存儲盤/yoryky.txt,根本是找不到/storage/emulated/0這個路徑的。

這裏寫圖片描述

另外我們還可以根據Context對象提供的方法來獲取sd卡的存儲路徑

getExternalCacheDir().getAbsolutePath()

/storage/emulated/0/Android/data/packagename/cache

該路徑會在sd卡下Android/data/路徑下創建packagename路徑並最終創建一個cahce目錄,在刪除app時,這個目錄也會被刪除。

getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath:

/storage/emulated/0/Android/data/packagename/files/Pictures

這個路徑是在上面講到cache目錄的同級目錄下創建一個files目錄,並在其中闖將存放圖片的Pictures目錄。getExternalFilesDir方法中可以傳多種參數,例如還可以傳Environment.DIRECTORY_DCIM這個參數一遍在files目錄下創建DCIM這個目錄。

由此我們知道獲取sd卡路徑的方法有兩套,一套是通過Environment類獲取packagename無關的路徑,一套是通過Context類獲取packagename相關的路徑,packagename路徑下可以有cache和files兩個目錄。

這裏的cache以及files兩個目錄在手機中的路徑爲/存儲盤/sd/Android/data/packagename/中。

b、獲取內存卡相關路徑方法

和獲取sd卡路徑不同,獲取內存卡路徑不能通過Environment類來獲取,只能通過Context來獲取

getCacheDir().getAbsolutePath()

/data/user/0/packagename/cache
getFilesDir().getAbsolutePath()

/data/user/0/com.yoryky.demo/files

可以看出Context提供的兩個方法,一個用來獲取cache目錄路徑,一個用來獲取files目錄路徑。這個的/data/user/0/代表多用戶(android 4.2版本開始支持多用戶)中的第一個用戶的存儲路徑,這個在手機上也是找不到的,實際上cache和files在手機中的路徑如下

這裏寫圖片描述

看的出來,手機上cache和files的實際路徑爲/存儲盤/Android/data/packagename/。

2、讀寫sd card路徑中文件

第一小節講了獲取sd卡目錄路徑以及內存卡目錄路徑的方法,這裏先來說說讀寫sd卡路徑中文件的方法實現

a、寫sd卡中的文件方法

這裏通過FileOutputStream類來實現寫sd卡文件

/**
 * 將內容寫入sd卡中
 * @param filename 要寫入的文件名
 * @param content  待寫入的內容
 * @throws IOException
 */
public static void writeExternal(Context context, String filename, String content) throws IOException {

    //獲取外部存儲卡的可用狀態
    String storageState = Environment.getExternalStorageState();

    //判斷是否存在可用的的SD Card
    if (storageState.equals(Environment.MEDIA_MOUNTED)) {

        //路徑: /storage/emulated/0/Android/data/com.yoryky.demo/cache/yoryky.txt
        filename = context.getExternalCacheDir().getAbsolutePath()  + File.separator + filename;

        FileOutputStream outputStream = new FileOutputStream(filename);
        outputStream.write(content.getBytes());
        outputStream.close();
    }
}

這個代碼很簡單,而且註釋也很詳細,這裏就不解釋了。

b、讀sd卡中的文件方法

通過FileInputStream來獲取sd卡中對應文件的內容

/**
 * 從sd card文件中讀取數據
 * @param filename 待讀取的sd card
 * @return
 * @throws IOException
 */
public static String readExternal(Context context, String filename) throws IOException {
    StringBuilder sb = new StringBuilder("");
    if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
        filename = context.getExternalCacheDir().getAbsolutePath() + File.separator + filename;
        //打開文件輸入流
        FileInputStream inputStream = new FileInputStream(filename);

        byte[] buffer = new byte[1024];
        int len = inputStream.read(buffer);
        //讀取文件內容
        while(len > 0){
            sb.append(new String(buffer,0,len));

            //繼續將數據放到buffer中
            len = inputStream.read(buffer);
        }
        //關閉輸入流
        inputStream.close();
    }
    return sb.toString();
}

通過FileInputStream對象遍歷便可以獲取對應文件中的內容。

3、讀寫內存卡中的文件

其實續寫內存卡中的文件方法和讀寫sd卡文件方法基本一致,就是文件路徑改變了而已。

a、寫內存卡中文件方法

這裏也直接給出實現

/**
 * 寫Internal Card文件
 * @param context
 * @param filename
 * @param content
 * @throws IOException
 */
public static void writeInternal(Context context, String filename, String content) throws IOException{
    //獲取文件在內存卡中files目錄下的路徑
    File file = context.getFilesDir();
    filename = file.getAbsolutePath() + File.separator + filename;

    //打開文件輸出流
    FileOutputStream outputStream = new FileOutputStream(filename);

    //寫數據到文件中
    outputStream.write(content.getBytes());
    outputStream.close();
}

這裏還是通過FileOutputStream類來寫數據到文件中。

b、讀內存卡中文件方法

還是直接給代碼

/**
 * 讀內存卡中文件方法
 * @param context  
 * @param filename 文件名
 * @return
 * @throws IOException
 */
public static String readInternal(Context context,String filename) throws IOException{
    StringBuilder sb = new StringBuilder("");

    //獲取文件在內存卡中files目錄下的路徑
    File file = context.getFilesDir();
    filename = file.getAbsolutePath() + File.separator + filename;

    //打開文件輸入流
    FileInputStream inputStream = new FileInputStream(filename);

    byte[] buffer = new byte[1024];
    int len = inputStream.read(buffer);
    //讀取文件內容
    while(len > 0){
        sb.append(new String(buffer,0,len));

        //繼續將數據放到buffer中
        len = inputStream.read(buffer);
    }
    //關閉輸入流
    inputStream.close();
    return sb.toString();
}

這裏依然通過FileInputStream來獲取文件中的數據。

到這裏讀寫sd卡以及內存卡中的文件方法就算是寫完了,實際上有這四個方法,我麼就可以封裝一個自己的FileUtil類來專門處理文件的讀寫操作了。這裏還是給一個demo地址吧,Android Demo.

4、參考文獻

1、Android常見文件路徑介紹

2、Android讀寫文件

3、Android SD卡簡單的文件讀寫操作

4、Android 文件的讀取和寫入

這幾個參考文獻可好好看看,特別是前兩篇,第一篇說清楚了sd卡和內存卡路徑的作用和獲取方式,而第二篇說清了android中其它文件的獲取方式寶座資源文件以及assets中的文件獲取方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章