Android開發過程當中,咱們常常會須要存儲文件,因此咱們也應該整理一下這方面的相關知識,維護好用戶設備的文件,更須要知道內部存儲和外部存儲的區別。java
先來看一下咱們本章節的思惟導圖,但願可以幫助你用碎片化或者儘可能短的時間,直白、深入的瞭解本文的知識點。android
是否須要用戶權限:否數據庫
是否能被其餘應用訪問:否緩存
卸載應用數據是否被刪除:是安全
內部存儲控件不須要用戶權限,這意味着咱們不須要用戶去受權android.permission.WRITE_EXTERNAL_STORAGE
和android.permission.READ_EXTERNAL_STORAGE
咱們就能夠讀寫該目錄下的文件。並且該目錄下的文件不能被其餘應用訪問。這也就保證了咱們應用內部存儲的文件的安全性和隱私性,若是咱們須要查看本身應用內部的文件,咱們能夠經過Android Studio的Device File Explore工具進行訪問:app
咱們能夠訪問/data/data/應用包名,查看本身應用下的內部存儲文件。工具
/data/data/應用名/cache :存放的是APP的緩存信息優化
/data/data/應用名/code_cache :在運行時存放應用產生的編譯或者優化的代碼this
/data/data/應用名/files : 存放APP的文件信息spa
還有一些運行時,產生的文件夾,例如調用SharedPreference所產生的 /data/data/應用包名/shared_prefs 目錄,存放着app的SharedPreference所產生的xml文件,還有調用數據庫所產生的 **/data/data/應用包名/databases/**文件夾,這裏就不一一舉例。
File getCacheDir() 返回內部存儲的cache文件夾
Log.d("DaMai",getCacheDir().getPath()); //data/user/0/com.example.vicky.yinji/cache
複製代碼
File getCodeCacheDir() 返回內部存儲的code_cache文件夾,要求Android5.0+
Log.d("DaMai",getCodeCacheDir().getPath()); ///data/user/0/com.example.vicky.yinji/code_cache
複製代碼
File getFilesDir() 訪問內部存儲的files目錄
Log.d("DaMai",getFilesDir().getPath()); ///data/user/0/com.example.vicky.yinji/files
複製代碼
String[] fileList() 返回files目錄下的文件名,例如files目錄下有test.txt文件和test1.txt文件
//輸出 test.txt和test1.txt
for (String item : fileList()){
Log.d("DaMai",item);
}
複製代碼
FileOutputStream openFileOutput() 寫文件到files目錄下:
try {
FileOutputStream outputStream = openFileOutput("test.txt", Context.MODE_PRIVATE);
outputStream.write("this is test content".getBytes());
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
複製代碼
此時file目錄下就會多了一個test.txt文件
FileInputStream openFileInput() 讀files目錄下文件,例如咱們讀剛剛寫入的test.txt文件
// 輸出:this is test content
try {
FileInputStream fileInputStream = openFileInput("test.txt");
byte[] bytes = new byte[1024];
StringBuffer stringBuffer = new StringBuffer();
int len = 0;
while ((len=fileInputStream.read(bytes))!=-1){
stringBuffer.append(new String(bytes,0,len));
}
Log.d("DaMai",stringBuffer.toString());
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
複製代碼
File getDataDir() 返回內部存儲的根文件夾,要求Android7.0+
Log.d("DaMai",getDataDir().getPath()); ///data/user/0/com.example.vicky.yinji
複製代碼
是否須要用戶權限:是
是否能被其餘應用訪問:是
卸載應用數據是否被刪除:否
公共目錄必須須要用戶受權讀寫的權限,這意味着咱們須要在AndroidManifest.xml
中註冊用戶權限。
<!-- 往SDCard寫入數據權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
複製代碼
而且在Android 6.0系統以後須要申請用戶權限,並得到用戶受權,才能讀寫文件。
公共目錄相對開放,咱們能夠訪問其餘APP存在公共目錄下的文件,而且當APP被刪除時,並不會刪除應用存在公共目錄下的文件。
咱們能夠經過Environment對象,訪問讀寫公共目錄的文件。接下來讓咱們看看相關的API。
File Environment.getExternalStorageDirectory() 訪問外部存儲設備公共根目錄:
//輸出:/storage/emulated/0
Log.d("DaMai",Environment.getExternalStorageDirectory().getPath());
複製代碼
File Environment.getExternalStoragePublicDirectory(String type)
咱們能夠經過type訪問公有目錄下對應的文件,例如:
//輸出:/storage/emulated/0/Music
Log.d("DaMai",Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getPath());
複製代碼
Environment對象爲咱們提供了豐富的訪問對應公有目錄下的type,咱們能夠經過Environment對象源碼進行查看,這裏再也不贅述。
String Environment.getExternalStorageState() 得到外部存儲SD卡的狀態,在讀寫SD卡的時候,咱們應該先判斷一下SD卡的狀態,是否可以支持讀寫。
具體返回值及對應的狀態也能夠查看Environment.getExternalStorageState的源碼。
是否須要用戶權限:4.4以上不須要
是否能被其餘應用訪問:否
卸載應用數據是否被刪除:是
私有目錄,在Android4.4系統以上。不須要註冊和用戶受權SD讀寫的權限,就能夠在應用的私有目錄進行讀寫文件。而且文件不能被其餘應用所訪問,具備較好的隱私性和安全性,而且在用戶刪除的時候,對應的應用私有目錄也會被刪除。
私有目錄地址:/storage/emulated/0/Android/data/應用包名
私有目錄下訪問的API都在ContextWrapper對象上。這意味這咱們能夠直接在Activity中調用或者經過Context對象去調用。
File Context.getExternalCacheDir() 訪問/storage/emulated/0/Android/data/應用包名/cache目錄,該目錄用來存放應用的緩存文件,當咱們經過應用刪除緩存文件的時候,該目錄下的文件會被清除。
//輸出:/storage/emulated/0/Android/data/com.example.vicky.yinji/cache
Log.d("DaMai",this.getExternalCacheDir().getPath());
複製代碼
File Context.getExternalFilesDir(String type) 訪問/storage/emulated/0/Android/data/應用包名/files 目錄,該目錄用來存放應用的數據,當咱們經過應用去清除應用數據的時候,該目錄下的文件會被清除。咱們也能夠經過type,去建立並得到對應目錄下的File文件。例如:
//建立並輸出:/storage/emulated/0/Android/data/com.example.vicky.yinji/files/test
Log.d("DaMai",this.getExternalFilesDir("test").getPath());
複製代碼
咱們也能夠將type傳爲null,這時候訪問的目錄就是files目錄,例如:
//輸出:/storage/emulated/0/Android/data/com.example.vicky.yinji/files
Log.d("DaMai",this.getExternalFilesDir(null).getPath());
複製代碼
咱們開發中常常會進行文件存儲,此次咱們終於弄清楚了Android的文件存儲,當咱們須要存儲一些私密性和安全性比較高的小數據,例如用戶的帳號密碼等信息,咱們能夠存放在內部存儲空間上;當咱們須要存放一些可以被其餘應用也能訪問的數據,而且當應用被刪除的時候,不但願數據被清除的時候,咱們能夠放到外部存儲的公有目錄下,但別忘了申請讀寫SD卡的權限哦;當咱們須要存放一些應用的數據和緩存數據,但願有較好的隱私性和應用被刪除的時候,對應的應用數據和緩存也被刪除,這時候咱們能夠選擇存放在外部存儲的私有目錄下。
我是大麥,若是喜歡個人文章,請給我一顆當心心。