一、概述
對於Android
系統中的儲存,一般分為以下三個方面:
- 內部儲存
- 外部儲存
- 外部快取目錄
- 外部永久目錄
SD
卡儲存
二、內部儲存
2.1 內部儲存的特點
內部儲存指的是下面這個路徑下的資料夾或者檔案:
/data/data/應用包名/
複製程式碼
截圖如下:
對於內部儲存來說,有這麼幾個特點:- 應用不需要宣告讀寫許可權就能操作這個目錄下的資料夾或者檔案
- 一般情況下,只有應用本身具有操作該目錄的權利
- 當應用解除安裝之後,該目錄也會被刪除
- 這部分目錄,普通使用者通過手機自帶的檔案管理器是看不到的,除非使用
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
卡,它主要解決上面內部儲存的兩個問題:
- 外部應用無法訪問
- 資料隨著應用資料被解除安裝而被刪除了
也就是下面截圖中部分的儲存:
3.1 獨立於應用的外部儲存
這部分儲存的特點是:
- 需要申請讀寫許可權才能訪問
- 任何有許可權的應用都可以訪問它
- 不會隨著應用的解除安裝而被刪除
由於這部分的儲存和應用無關,因此它的方法都不是通過Context
來呼叫,而是通過Environment
的靜態方法來返回一個File
物件,我們再通過這個File
物件進行操作。
getRootDirectory
返回是/system
目錄,它和/sdcard
以及/data
是同級的.getExternalStorageDirectory
返回的是外部儲存的根目錄,也就是我們平時從檔案管理器中能看到的最頂級目錄,它的File
絕對路徑為:/storage/emulated/0
getDownloadCacheDirectory
返回是/cache
目錄,它和/system
以及/data
是同級的.getExternalStoragePublicDirectory(String type)
其中,type
的選項有如下幾種: 最終得到的資料夾管理器下面的幾個一級目錄,例如DIRECTORY_DCIM
得到的就是下面這個目錄:
3.2 和應用相關的外部儲存
這部分儲存的特點是:
4.4
以後不需要申請讀寫許可權也能訪問- 隨著應用的解除安裝而被刪除
- 該目錄可以被其它應用訪問
這部分儲存的位置位於/Android/data/應用包名/
下,例如下面這樣,就是com.android.browser
的應用相關外部儲存:
getExternalCacheDir()
返回的是/Android/data/應用包名/cache
目錄所對應的File
物件getExternalFilesDir(String type)
type
和Environment
中定義的型別相同,根據type
的不同返回不同的File
物件,例如DIRECTORY_DCIM
,那麼得到的是/Android/data/應用包名/files/DCIM
所對應的File
物件。