淺析Android文件存儲
一、內(nèi)部存儲
內(nèi)部存儲,位于data/data/包名/路徑下
是否需要用戶權(quán)限:否
是否能被其他應(yīng)用訪問:否
卸載應(yīng)用數(shù)據(jù)是否被刪除:是
內(nèi)部存儲控件不需要用戶權(quán)限,這意味著我們不需要用戶去授權(quán)下面的權(quán)限:
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAGE
對于設(shè)備中每一個(gè)安裝的 App,系統(tǒng)都會在 data/data 目錄下以應(yīng)用程序包名自動(dòng)創(chuàng)建與之對應(yīng)的文件夾,可以直接讀寫該目錄下的文件。而且該目錄下的文件不能被其他應(yīng)用訪問。這也就保證了我們應(yīng)用內(nèi)部存儲的文件的安全性和隱私性,如果我們需要查看自己應(yīng)用內(nèi)部的文件,我們可以通過 Android Studio的Device File Explore工具進(jìn)行訪問:
通過這個(gè),可以查看對應(yīng)應(yīng)用的存儲文件。
/data/data/應(yīng)用名/cache :存放的是APP的緩存信息
/data/data/應(yīng)用名/code_cache :在運(yùn)行時(shí)存放應(yīng)用產(chǎn)生的編譯或者優(yōu)化的代碼
/data/data/應(yīng)用名/files : 存放APP的文件信息
還有一些運(yùn)行時(shí),產(chǎn)生的文件夾,例如調(diào)用 SharedPreference 所產(chǎn)生的 /data/data/應(yīng)用包名/shared_prefs 目錄,存放著 app 的 SharedPreference 所產(chǎn)生的 xml 文件,還有調(diào)用數(shù)據(jù)庫所產(chǎn)生的 **/data/data/應(yīng)用包名/databases/** 文件夾,這里就不一一舉例。
從技術(shù)上來講如果你在創(chuàng)建內(nèi)部存儲文件的時(shí)候?qū)⑽募傩栽O(shè)置成可讀,其他 app 能夠訪問自己應(yīng)用的數(shù)據(jù),前提是他知道你這個(gè)應(yīng)用的包名,如果一個(gè)文件的屬性是私有(private),那么即使知道包名其他應(yīng)用也無法訪問。 內(nèi)部存儲空間十分有限,因而顯得可貴,另外,它也是系統(tǒng)本身和系統(tǒng)應(yīng)用程序主要的數(shù)據(jù)存儲所在地,一旦內(nèi)部存儲空間耗盡,手機(jī)也就無法使用了。所以對于內(nèi)部存儲空間,我們要盡量避免使用。Shared Preferences 和 SQLite 數(shù)據(jù)庫都是存儲在內(nèi)部存儲空間上的。內(nèi)部存儲一般用 Context 來獲取和操作。
訪問內(nèi)部存儲的API方法:
1.getFilesDir().getAbsolutePath() :/data/user/0/com.example.myapplication/files
2.getCacheDir().getAbsolutePath() :/storage/emulated/0/Android/data/com.example.myapplication/cache
3.getDir(“myFile”, MODE_PRIVATE).getAbsolutePath() :/data/user/0/com.example.myapplication/app_myfile
4.getCodeCacheDir().getAbsolutePath() : /data/user/0/com.example.myapplication/code_cache ,要求Android5.0+
二、外部存儲
概念:最容易混淆的是外部存儲,因?yàn)槔系?Android 系統(tǒng)的跟新的 Android 系統(tǒng)是有差別的,很多人去網(wǎng)上查找資料,看了一下以前的資料,又看了一下現(xiàn)在的資料,但是發(fā)現(xiàn)它們說法不一樣然后就困惑了。
首先說一個(gè)大家普遍的概念 "如果在 pc 機(jī)上是區(qū)分外部存儲和內(nèi)部存儲的話,那么電腦自帶的硬盤算是內(nèi)部存儲,U盤或者移動(dòng)硬盤就是外部存儲了。" 因此很多人帶著這樣的理解去看待安卓手機(jī),把內(nèi)置存儲(機(jī)身存儲)當(dāng)做內(nèi)部存儲,而把擴(kuò)展的 SD 卡當(dāng)做是外部存儲。
這么認(rèn)為確實(shí)沒錯(cuò),因?yàn)樵?4.4(API19)以前的手機(jī)上確實(shí)是這樣的,手機(jī)自身帶的存儲卡就是內(nèi)部存儲,而擴(kuò)展的SD卡就是外部存儲。
但是從 4.4 的系統(tǒng)開始,很多的中高端機(jī)器都將自己的機(jī)身存儲擴(kuò)展到了 8G 以上,比如有的人的手機(jī)是 16G 的,有的人的手機(jī)是 32G 的,但是這個(gè) 16G,32G 是內(nèi)部存儲嗎,不是的,它們依然是外部存儲。
也就是說 4.4 系統(tǒng)及以上的手機(jī)將機(jī)身存儲存儲(手機(jī)自身帶的存儲叫做機(jī)身存儲)在概念上分成了 "內(nèi)部存儲internal" 和 "外部存儲external" 兩部分。既然 16G,32G 是外部存儲,那有人又有疑惑了,那 4.4 系統(tǒng)及以上的手機(jī)要是插了 SD 卡呢,SD 卡又是什么呢,如果 SD 卡也是外部存儲的話,那怎么區(qū)分機(jī)身存儲的外部存儲跟 SD 卡的外部存儲呢?
對,SD卡也是外部存儲,那怎么區(qū)分呢,在4.4以后的系統(tǒng)中,API提供了這樣一個(gè)方法來遍歷手機(jī)的外部存儲路徑:
File[] files; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { files = getExternalFilesDirs(Environment.MEDIA_MOUNTED); for(File file:files){ Log.e("main",file); } }
如果你的手機(jī)插了SD卡的話,那么它打印的路徑就有兩條了,例如我的華為榮耀 7 插了SD卡,它的結(jié)果如下:
/storage/emulated/0/Android/data/packname/files/mounted
/storage/B3E4-1711/Android/data/packname/files/mounted
其中 /storage/emulated/0 目錄就是機(jī)身存儲的外部存儲路徑,而 /storage/B3E4-1711/ 就是 SD 卡的路徑,他們統(tǒng)稱為外部存儲。
一般對于外部存儲可以分為兩類,外部公有和外部私有。
2.1、外部公有
是否需要用戶權(quán)限:是
是否能被其他應(yīng)用訪問:是
卸載應(yīng)用數(shù)據(jù)是否被刪除:否
公共目錄必須需要用戶授權(quán)讀寫的權(quán)限,這意味著我們需要在AndroidManifest.xml
中注冊用戶權(quán)限。
<!-- 外部存儲寫入數(shù)據(jù)權(quán)限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
并且在 Android 6.0 系統(tǒng)之后需要申請用戶權(quán)限,并獲得用戶授權(quán),才能讀寫文件。
公共目錄相對開放,我們可以訪問其他APP存在公共目錄下的文件,并且當(dāng) APP 被刪除時(shí),并不會刪除應(yīng)用存在公共目錄下的文件。
我們可以通過 Environment 對象,訪問讀寫公共目錄的文件。
在對外部存儲進(jìn)行讀寫的時(shí)候,應(yīng)該先判斷一下外部存儲的狀態(tài),是否能夠支持讀寫。
Environment.getExternalStorageState() /** {@link #MEDIA_UNKNOWN}, {@link #MEDIA_REMOVED}, * {@link #MEDIA_UNMOUNTED}, {@link #MEDIA_CHECKING}, * {@link #MEDIA_NOFS}, {@link #MEDIA_MOUNTED}, * {@link #MEDIA_MOUNTED_READ_ONLY}, {@link #MEDIA_SHARED}, * {@link #MEDIA_BAD_REMOVAL}, or {@link #MEDIA_UNMOUNTABLE} */
只有在返回值為MEDIA_MOUNTED 表示當(dāng)前是可正常讀寫的。
接下來讓我們看看相關(guān)的API。
1. Environment.getExternalStorageDirectory() : /storage/emulated/0
2. Environment.getExternalStoragePublicDirectory(String type)
Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getAbsolutePath() : /storage/emulated/0/Documents
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath() : /storage/emulated/0/Music
2.2、外部私有
是否需要用戶權(quán)限:4.4以上不需要
是否能被其他應(yīng)用訪問:否
卸載應(yīng)用數(shù)據(jù)是否被刪除:是
私有目錄,在 Android4.4 系統(tǒng)以上。不需要注冊和用戶授權(quán)外部私有存儲的讀寫的權(quán)限,就可以在應(yīng)用的外部私有進(jìn)行讀寫文件。并且文件不能被其他應(yīng)用所訪問,具有較好的隱私性和安全性,并且在用戶刪除的時(shí)候,對應(yīng)的應(yīng)用私有目錄也會被刪除。
私有目錄地址:/storage/emulated/0/Android/data/應(yīng)用包名
相關(guān)API如下:
getExternalCacheDir().getAbsolutePath() // /storage/emulated/0/Android/data/com.example.myapplication/cache
getExternalFilesDir("mytest").getAbsolutePath() // /storage/emulated/0/Android/data/com.example.myapplication/files/mytest
getExternalFilesDir(null).getAbsolutePath() // /storage/emulated/0/Android/data/com.example.myapplication/files
以上就是淺析Android文件存儲的詳細(xì)內(nèi)容,更多關(guān)于Android文件存儲的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android三方依賴沖突Gradle中exclude的使用
這篇文章主要介紹了Android三方依賴沖突Gradle中exclude的使用,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09android 之Spinner下拉菜單實(shí)現(xiàn)級聯(lián)
android 之Spinner下拉菜單實(shí)現(xiàn)級聯(lián),需要的朋友可以參考一下2013-02-02Android使用RadioGroup實(shí)現(xiàn)底部導(dǎo)航欄
這篇文章主要為大家詳細(xì)介紹了Android使用RadioGroup實(shí)現(xiàn)底部導(dǎo)航欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08Android 第三方應(yīng)用接入微信平臺研究情況分享(一)
微信平臺開放后倒是挺火的,許多第三方應(yīng)用都想試下接入微信這個(gè)平臺,畢竟可以利用微信建立起來的關(guān)系鏈來拓展自己的應(yīng)用還是挺不錯(cuò)的 最近由于實(shí)習(xí)需要也在研究這個(gè)東西,這里把我的整個(gè)研究情況給出來2013-01-01Android Material設(shè)計(jì)中列表和卡片的創(chuàng)建方法解析
這篇文章主要介紹了Android Material設(shè)計(jì)中列表和卡片的創(chuàng)建方法解析,列表和卡片是Material Design視圖中的重要部分,需要的朋友可以參考下2016-04-04Android基礎(chǔ)之獲取LinearLayout的寬高
LinearLayout是線性布局控件,它包含的子控件將以橫向或豎向的方式排列,按照相對位置來排列所有的widgets或者其他的containers,超過邊界時(shí),某些控件將缺失或消失。有的時(shí)候,我們需要想獲取LinearLayout寬高,下面通過這篇文章來跟著小編一起學(xué)習(xí)學(xué)習(xí)吧。2016-11-11