Android 資料儲存知識梳理(2) Android儲存目錄

澤毛發表於2017-12-21

一、概述

對於Android系統中的儲存,一般分為以下三個方面:

  • 內部儲存
  • 外部儲存
  • 外部快取目錄
  • 外部永久目錄
  • SD卡儲存

二、內部儲存

2.1 內部儲存的特點

內部儲存指的是下面這個路徑下的資料夾或者檔案:

/data/data/應用包名/
複製程式碼

截圖如下:

Android 資料儲存知識梳理(2)   Android儲存目錄
對於內部儲存來說,有這麼幾個特點:

  • 應用不需要宣告讀寫許可權就能操作這個目錄下的資料夾或者檔案
  • 一般情況下,只有應用本身具有操作該目錄的權利
  • 當應用解除安裝之後,該目錄也會被刪除
  • 這部分目錄,普通使用者通過手機自帶的檔案管理器是看不到的,除非使用Root Explorer等工具才可以看到,並且要申請Root許可權才能進行讀寫操作。

Android提供了一些方法來操作內部儲存的路徑,我們可以選擇它作為我們提供的標準目錄,也可以自己建立目錄,下面我們開始介紹。

2.2 標準檔案目錄/data/data/應用包名/files

  • files目錄下建立、讀寫檔案,可以用下面這一對方法
    public static void writeToPrivateFile(Context context, String str, String path) {
        FileOutputStream fileOutputStream = null;
        BufferedWriter bufferedWriter;
        try {
            fileOutputStream = context.openFileOutput(path, Context.MODE_APPEND);
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream));
            bufferedWriter.write(str);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static String readFromPrivateFile(Context context, String path) {
        FileInputStream fileInputStream = null;
        BufferedReader bufferedReader;
        String result = null;
        try {
            fileInputStream = context.openFileInput(path);
            bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result != null ? result : "";
    }
複製程式碼
  • files目錄下建立新的目錄 上面的方法是直接開啟輸入輸出流,讀寫位於files根目錄下的檔案,如果我們希望進行更靈活的操作,那麼通過下面方法可以獲得files資料夾所指向的File物件,再通過這個返回的File物件操作:
File file = context.getFilesDir();
複製程式碼
  • 列出files目錄下的所有檔名
String[] files = context.fileList();
複製程式碼
  • 刪除files目錄下的檔案
context.deleteFile(path);
複製程式碼

2.3 標準快取目錄data/data/應用包名/cache

files目錄相比,cache目錄有一個特點:就是當系統儲存空間不足時,會刪除其中的資料夾:

File cacheFile = context.getCacheDir();
複製程式碼

2.4 程式碼快取目錄data/data/應用/code_cache

它和上面cache目錄類似,都是隻能得到一個File物件,同樣的,它也有一個特點,就是當App升級時,會刪除該目錄下的內容,這個API要求大於21

File code = context.getCodeCacheDir()
複製程式碼

2.5 SharePreference和資料庫儲存的目錄

在平時的開發中,我們經常會用到SharePreference來儲存資料,這些資料就位於:/data/data/應用包名/shared_prefs目錄下,而資料庫則儲存在/data/data/應用包名/databases下。

2.6 根目錄

除了使用上面四種根目錄之外,我們還可以直接在data/data/應用包名目錄下新建目錄,呼叫下面的方法會我們在/data/data/應用包名/目錄下新建一個名字為app_<path>的資料夾,並返回這個資料夾的File物件,之後,我們再通過這個物件進行相應的操作:

File dir = context.getDir(path, Context.MODE_APPEND);
複製程式碼

三、外部儲存

這裡指的外部儲存是我們平時常說的32g/64g,它是手機出廠時自帶的,不需要再額外的插入SD卡,它主要解決上面內部儲存的兩個問題:

  • 外部應用無法訪問
  • 資料隨著應用資料被解除安裝而被刪除了

也就是下面截圖中部分的儲存:

Android 資料儲存知識梳理(2)   Android儲存目錄

3.1 獨立於應用的外部儲存

這部分儲存的特點是:

  • 需要申請讀寫許可權才能訪問
  • 任何有許可權的應用都可以訪問它
  • 不會隨著應用的解除安裝而被刪除

由於這部分的儲存和應用無關,因此它的方法都不是通過Context來呼叫,而是通過Environment的靜態方法來返回一個File物件,我們再通過這個File物件進行操作。

  • getRootDirectory 返回是/system目錄,它和/sdcard以及/data是同級的.
  • getExternalStorageDirectory 返回的是外部儲存的根目錄,也就是我們平時從檔案管理器中能看到的最頂級目錄,它的File絕對路徑為:/storage/emulated/0
  • getDownloadCacheDirectory 返回是/cache目錄,它和/system以及/data是同級的.
  • getExternalStoragePublicDirectory(String type) 其中,type的選項有如下幾種:
    Android 資料儲存知識梳理(2)   Android儲存目錄
    最終得到的資料夾管理器下面的幾個一級目錄,例如DIRECTORY_DCIM得到的就是下面這個目錄:
    Android 資料儲存知識梳理(2)   Android儲存目錄

3.2 和應用相關的外部儲存

這部分儲存的特點是:

  • 4.4以後不需要申請讀寫許可權也能訪問
  • 隨著應用的解除安裝而被刪除
  • 該目錄可以被其它應用訪問

這部分儲存的位置位於/Android/data/應用包名/下,例如下面這樣,就是com.android.browser的應用相關外部儲存:

Android 資料儲存知識梳理(2)   Android儲存目錄

  • getExternalCacheDir() 返回的是/Android/data/應用包名/cache目錄所對應的File物件
  • getExternalFilesDir(String type) typeEnvironment中定義的型別相同,根據type的不同返回不同的File物件,例如DIRECTORY_DCIM,那麼得到的是/Android/data/應用包名/files/DCIM所對應的File物件。

相關文章