storage路徑問題

1 概念總述linux

android開發中,關於存儲路徑,咱們常常聽到如下幾個概念:內存、內部存儲和外部存儲,如今咱們就來詳細說說這三者區別與聯繫。android

內存:英文中記爲memory,即RAM數據庫

內部存儲:英文記爲InternalStorage,即內部ROMapi

外部存儲:英文記爲ExternalStorage, 即外部ROM和SDCard緩存

由上可知三者在英文中不會產生太大的歧義,可是當咱們翻譯爲中文後,對於三者之間的關係就開始模糊化了。最容易混淆的是外部存儲,咱們廣泛認爲機身固有的存儲是內部存儲,而擴展的T卡是外部存儲。早期的android設備內部存儲確實是固定的,而外部存儲確實是能夠像U盤同樣移動的。可是在後來的設備中,不少中高端的機器都將本身的機身存儲擴展到了8G以上,他們將存儲在概念上分紅了"內部internal"和"外部external"兩部分,但其實都在手機內部。因此無論android手機是否有可移動的sdcard,他們老是有外部存儲和內部存儲。最關鍵的是,咱們都是經過相同的api來訪問可移動的sdcard或者手機自帶的存儲。微信

Android 內存app

手機的整個存儲空間分爲內部存儲和外部存儲兩部分,內部存儲中又包含RAM和ROM等部分。函數

內部存儲,即InternalStorage,也常說內置存儲卡,這是手機內置的存儲空間,出廠時就被肯定,是手機的一個硬件指標。類比電腦的內存。測試

外部存儲,即ExternalStorage,也常說外置存儲卡,手機出廠時並不存在,是由用戶自由擴展的存儲空間,常見的就是SD卡。類比電腦的外接移動硬盤。
RAM,即常說的運行時內存,是手機運行時存儲數據和指令的地方,注意是運行時內存。類比電腦的內存條。spa

ROM,用來存放一些系統文件,應用配置和其餘數據的地方,是內部存儲中主要存儲區域。類比於Windows電腦的C盤。

 

在 Android Studio 使用 DDMS 的 File Exploer 窗口中查看文件系統,下圖就是一個 Android 文件系統目錄。

Android 文件系統目錄

這裏有三個文件夾須要注意,data、mnt和storage,data是指內部存儲,mnt和storage指外部存儲。下面將詳細介紹內部存儲和外部存儲。

 

2 內部存儲

內部存儲位於系統中很特殊的一個位置,若是你想將文件存儲於內部存儲中,那麼文件默認只能被你的應用訪問到,且一個應用建立的全部文件都在和應用包名相同的目錄下。當一個應用卸載後,內部存儲中的這些文件也被刪除。內部存儲空間十分有限,它是系統自己和系統應用程序主要的數據存儲所在地,一旦內部存儲空間耗盡,手機就沒法使用了。Shared Preferences和SQLite數據庫都是存儲在內部存儲空間上的。內部存儲通常用Context來獲取和操做。內部存儲有兩個重要目錄:

1)app文件夾:沒有root的手機不能打開該文件夾。app文件夾裏存放着系統中安裝的第三方應用的apk文件,當咱們調試一個app的時候,能夠看到控制檯輸出的內容,有一項是uploading...,就是上傳咱們的apk到這個文件夾,上傳成功後纔開始安裝。

2)data文件夾:

該文件夾存放存儲包私有數據,對於設備中每個安裝的 App,系統都會在內部存儲空間的 data/data 目錄下以應用包名爲名字自動建立與之對應的文件夾。
用戶卸載 App 時,系統自動刪除 data/data 目錄下對應包名的文件夾及其內容。
該目錄下又把存儲內容進行了分類:

  • data/data/包名/cache: 存放的 APP 的緩存信息
  • data/data/包名/databases: 存放 APP 的數據庫信息
  • data/data/包名/files: 存放 APP 的文件信息
  • data/data/包名/shared_prefs: 存放 APP 內的 SharedPreferences

3)路徑獲取API

/data
Environment.getDataDirectory();
/data/data/包名/files context.getFilesDir();
//對於 Files 目錄下的文件,一般不會經過 File 類的方式直接進行讀寫,而是利用一些封裝過的類或函數進行操做:
public FileInputStream openFileInput(String name) public FileOutputStream openFileOutput(String name, int mode)
//還能夠直接刪除或查詢該目錄下的文件: context.deleteFile(name) context.fileList()
/data/data/包名/cache context.getCacheDir();
/data/data/包名/shared_prefs context.getSharedPreferences(name,mode)//返回的是 SharedPreferences 對象 context.deleteSharedPreferences(name)
/data/data/包名/databases context.getDataDir() context.getDatabasePath(name) context.deleteDatabase(name)
/data/data/包名/app_name context.getDir(name,mode) //經測試該方法會在 /data/data/包名/ 目錄下生成一個以 app_ 開頭的目錄

 

3 外部存儲

 每一個兼容 Android 的設備都支持可用於保存文件的共享「外部存儲」。 該存儲多是可移除的存儲介質(例如 SD 卡)或內部(不可移除)存儲。 保存到外部存儲的文件是全局可讀取文件,並且,在計算機上啓用 USB 大容量存儲以傳輸文件後,可由用戶修改這些文件。

外部存儲就是文件系統目錄中看到的storage文件夾,也有多是mnt文件夾,在storage文件夾中有一個sdcard文件夾,這個文件夾中的文件又分爲兩類,一類是公有目錄,還有一類是私有目錄,好比DCIM,Download等這些系統爲咱們建立的文件夾,私有目錄就是android這個文件夾,這個文件夾打開后里邊有一個data文件夾,打開這個文件夾,裏面包含了許多包名組成的文件夾。
1)讀取狀態
要讀取或寫入外部存儲上的文件,應用必須獲取READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE系統權限。
Environment.getExternalStorageState()

返回值爲如下幾種:

MEDIA_MOUNTED:sd卡正常掛載

MEDIA_REMOVED:無介質

MEDIA_UNMOUNTED:有介質,未掛載,在系統中刪除

MEDIA_BAD_REMOVAL:介質在掛在前被移除,直接取出sd卡。

MEDIA_CHECKING:正在磁盤檢查,剛裝上sd卡時

MEDIA_SHARED:sd卡存在但沒有掛載,而且經過USB大容量存儲共享,操做打開USB存儲

MEDIA_MOUNTED_READ_ONLY:sd卡存在而且已掛載,可是掛載方式爲只讀

MEDIA_NOFS:介質存在可是爲空白,或用在不支持的文件系統

MEDIA_UNMOUNTABLE:存在sd卡可是不能掛載,例如發生介質損壞

掛載:這是linux系統的術語,就是加載的意思,把sd卡劃入系統相連,讓系統能認到並讀取sd卡的內容。

 

當sd卡狀態爲MEDIA_MOUNTED時,/mnt/sdcard目錄纔是可讀可寫,而且能夠建立目錄及文件。其餘狀況一概不可讀可寫。

讀取sd卡通常會這麼寫。

String state;
String path;
state = Environment.getExternalStorageState();
if(state.equals(Environment.MEDIA_MOUNTED)){
path = Environment.getExternalStorageDirectory().getAbsolutePath();
}
讀寫sd卡不要忘了權限問題,需加入如下兩個權限
* 1 在AndroidManifest文件中加入sdcard操做權限    <!--在SDCard中建立與刪除文件權限 -->    <uses-permissioandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>    <!--往SDCard寫入數據權限 -->    <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/> * 2 確認sdcard的存在    android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED) * 3 獲取擴展存儲設備的文件目錄   android.os.Environment.getExternalStorageDirectory();
2)公共目錄:

Android 在外部存儲上提供了十個公共目錄來存儲相對應的文件:
經過 API Environment.getExternalStoragePublicDirectory(type) 來訪問

  • DIRECTORY_MUSIC:/storage/emulated/0/Music
  • DIRECTORY_PODCASTS:/storage/emulated/0/Podcasts
  • DIRECTORY_RINGTONES:/storage/emulated/0/Ringtones
  • DIRECTORY_ALARMS:/storage/emulated/0/Alarms
  • DIRECTORY_NOTIFICATIONS:/storage/emulated/0/Notifications
  • DIRECTORY_PICTURES:/storage/emulated/0/Pictures
  • DIRECTORY_MOVIES:/storage/emulated/0/Movies
  • DIRECTORY_DOWNLOADS:/storage/emulated/0/Downloads
  • DIRECTORY_DCIM:/storage/emulated/0/Dcim
  • DIRECTORY_DOCUMENTS:/storage/emulated/0/Documents

3)私有目錄

Android2.2 引入了基於擴展存儲器的應用緩存目錄,該目錄指向大容量的擴展存儲器。與應用的內存私有目錄同樣,緩存目錄會隨着應用的卸載一併刪除。
和內部存儲同樣,會在 SD 卡的 Android/data 目錄下生成對應包名的文件夾

/storage/emulated/0/Android/data/應用包名/files
context.getExternalFilesDir(type)
/storage/emulated/0/Android/data/應用包名/cache context.getExternalCacheDir()
在 Android 目錄下除了 data 目錄還有一個 obb 目錄
/storage/emulated/0/Android/obb/應用包名 context.getObbDir()

 

4)其餘目錄

  1. /cache 目錄
    經過 API Environment.getDownloadCacheDirectory() 訪問,存儲下載文件的緩存路徑
  2. /system 目錄
    經過 API Environment.getRootDirectory() 訪問,該目錄下也有一個 app 目錄,存放的是系統應用的 apk 文件。
/system/app 和 /data/app 的區別
  • /data/app 裏軟件權限沒全開,/system/app 裏的軟件獲取了全部權限
  • /data/app 能夠應用卸載,/system/app 只能 root 後刪除
  • /data/app 文件夾大小隨便,/system/app 文件夾有大小限制
  • 卸載/system/app 目錄下的文件並不會增長系統空間,便可用 ROM 空間
  1. /mnt 目錄
    這個目錄專門用來看成掛載點掛在外部設備的,如 SD 卡,sdcard
    將會被系統視做一個文件夾,這個文件夾將會被系統嵌入到收集系統的 mnt 目錄中,因此在 /mnt 目錄下也會看到一個 sdcard 的快捷方式:

 

 4 總結

 A: getCacheDir(): 獲取/data/data//cache目錄

       getFileDir(): 獲取/data/data/files目錄

這兩個目錄中的內容必須是root的手機在文件操做系統中才能看到。固然若是在應用程序中清空數據或者卸載應用,那麼這兩個目錄下的文件也將會被清空的。

 

B:  getExternalFilesDir(): 獲取SDCard/Android/data/你的應用的包名/files/目錄(通常存放一些長時間保存的數據)

     getExternalCacheDir(): 獲取SDCard/Android/data/你的應用包名/cache/目錄(通常存放臨時緩存的數據)

這兩個是放在外置存儲卡的,這個目錄下的內容,可使用文件瀏覽系統查看到,可是若是清空數據或者卸載應用,這兩個目錄下的文件也將被清空。

當應用被用戶卸載後,SDCard/Android/data/你的應用包名/這個目錄下的全部文件都會被刪除,不會留下垃圾信息。A、B兩種方式的緩存都會在卸載app的時候被系統清理到,而開發者本身在sd卡上創建的緩存文件夾,是不會隨着app的卸載而被清除掉的。

getCacheDir:/data/data/com.example.sinatext/cache 
getFilesDir:/data/data/com.example.sinatext/files
 
getExternalCacheDir:/storage/sdcard0/Android/data/com.example.sinatext/cache
getExternalFilesDir:/storage/sdcard0/Android/data/com.example.sinatext/files/text

getDatabasePath:/data/data/com.example.sinatext/databases/text
getDir:/data/data/com.example.sinatext/app_modeDir
 
getPackageResourcePath:/data/app/com.example.sinatext-2.apk
Environment.getDataDirectory():/data
Environment.getExternalStorageState():mounted 
Environment.getDownloadCacheDirectory():/cache
 
Environment.getExternalStorageDirectory():/storage/sdcard0

Environment.getRootDirectory():/system

按照路徑的特徵,咱們又能夠將文件存儲的路徑分爲兩大類,一類是路徑中含有包名的,一類是路徑中不含有包名的,含有包名的路徑,由於和某個App有關,因此對這些文件夾的訪問都是調用Context裏邊的方法,而不含有包名的路徑,和某一個App無關,咱們能夠經過Environment中的方法來訪問。

清除數據:相似於恢復出廠設置,刪除了全部用戶保存的數據。則是指一些固定的用戶信息,好比登陸信息、進度保存信息等,清理以後,再次運行對應的App,好比微信,則須要從新輸入登陸信息,而若是是遊戲,特別是單機遊戲,則就像新遊戲同樣,以前的進度信息都會被清除而沒法繼續。即將外部私有數據包(/storage/emulated/0/Android/data/包名)清除,將內部數據下的全部內容(/data/data/包名/XXX)清除;

清除緩存:只是刪除了應用軟件的緩存資源。手機App應用在運行過程當中會產生一些臨時數據,好比加載過的頁面、填寫過的數據等,這些數據的存在有利於對應App無需屢次加載而運行加快,這些數據稱之爲「緩存數據「。清理緩存表示將這些臨時數據清除,清除後,對應App再次運行須要從新生成,可能會變慢,可是總體手機運行內存因其釋放而增長,反而可能加快。即將外部私有數據下的cache包(/storage/emulated/0/Android/data/包名/cache)清除,將內部數據下的cache包下的內容(/data/data/包名/cache/XXX)清除 。

 

參考博文http://blog.csdn.net/summerinnphuket/article/details/50790365https://www.jianshu.com/p/80e10b3dbba5
相關文章
相關標籤/搜索