版權聲明:本文為博主原創(chuàng)文章盖桥,未經(jīng)博主允許不得轉載。 https://blog.csdn.net/u010937230/article/details/73303034
前言:
對于任何一個應用來說镊讼,無論是PC端應用還是Android應用搁凸,存儲肯定是必不可少的。對于很多做Android開發(fā)的同學來說狠毯,可能認為文件存儲很簡單护糖,調用一些諸如getFilesDir,getExternalStorageDirectory方法行了嚼松,但是雖然說它們會調用相應的方法來實現(xiàn)簡單的數(shù)據(jù)存儲嫡良。但是他們未必就搞懂了他的數(shù)據(jù)到底存在了哪里,以及他的數(shù)據(jù)是否存對了地方献酗,或者是否做好了版本兼容寝受。下面我將從這幾個地方來解答大家常見的困惑:
1、Android中內部存儲罕偎,外部存儲的概念
2很澄、不同安卓版本下getDataDirectory,getFilesDir颜及,getCacheDir甩苛,getDir,getExternalStorageDirectory俏站,getExternalStoragePublicDirectory讯蒲,getExternalFilesDir,getExternalCacheDir肄扎,getExternalCacheDir墨林,getRootDirectory等方法的區(qū)別和聯(lián)系
3、清除數(shù)據(jù)和清除緩存到底清除了什么數(shù)據(jù)
4犯祠、/storage/sdcard旭等,/sdcard,/mnt/sdcard衡载,/storage/emulated/0之間的關系
5搔耕、一張圖看懂Ram,Rom月劈,以及擴展存儲(TF卡)的區(qū)別度迂;內部存儲,外部存儲的區(qū)別猜揪。
一惭墓、Android中內部存儲,外部存儲的概念
內部存儲
概念:注意內部存儲不是內存而姐。內部存儲位于系統(tǒng)中很特殊的一個位置腊凶,如果你想將文件存儲于內部存儲中,那么文件默認只能被你的應用訪問到拴念,且一個應用所創(chuàng)建的所有文件都在和應用包名相同的目錄下钧萍。也就是說應用創(chuàng)建于內部存儲的文件,與這個應用是關聯(lián)起來的政鼠。當一個應用卸載之后风瘦,內部存儲中的這些文件也被刪除。從技術上來講如果你在創(chuàng)建內部存儲文件的時候將文件屬性設置成可讀公般,其他app能夠訪問自己應用的數(shù)據(jù)万搔,前提是他知道你這個應用的包名,如果一個文件的屬性是私有(private)官帘,那么即使知道包名其他應用也無法訪問瞬雹。 內部存儲空間十分有限,因而顯得可貴刽虹,另外酗捌,它也是系統(tǒng)本身和系統(tǒng)應用程序主要的數(shù)據(jù)存儲所在地,一旦內部存儲空間耗盡涌哲,手機也就無法使用了胖缤。所以對于內部存儲空間,我們要盡量避免使用阀圾。Shared Preferences和SQLite數(shù)據(jù)庫都是存儲在內部存儲空間上的草姻。內部存儲一般用Context來獲取和操作。
訪問內部存儲的API方法:
1稍刀、Environment.getDataDirectory()
2撩独、getFilesDir().getAbsolutePath()
3、getCacheDir().getAbsolutePath()
4账月、getDir(“myFile”, MODE_PRIVATE).getAbsolutePath()
外部存儲
概念:最容易混淆的是外部存儲综膀,因為老的Android系統(tǒng)的跟新的Android系統(tǒng)是有差別的,很多人去網(wǎng)上查找資料局齿,看了一下以前的資料剧劝,又看了一下現(xiàn)在的資料,但是發(fā)現(xiàn)它們說法不一樣然后就困惑了抓歼。首先說一個大家普遍的概念“如果在pc機上是區(qū)分外部存儲和內部存儲的話讥此,那么電腦自帶的硬盤算是內部存儲拢锹,U盤或者移動硬盤就是外部存儲了√言”因此很多人帶著這樣的理解去看待安卓手機卒稳,把內置存儲(機身存儲)當做內部存儲,而把擴展的SD卡當做是外部存儲他巨。這么認為確實沒錯充坑,因為在4.4(API19)以前的手機上確實是這樣的,手機自身帶的存儲卡就是內部存儲染突,而擴展的SD卡就是外部存儲捻爷。但是從4.4的系統(tǒng)開始,很多的中高端機器都將自己的機身存儲擴展到了8G以上份企,比如有的人的手機是16G的也榄,有的人的手機是32G的,但是這個16G司志,32G是內部存儲嗎手蝎,不是的!@尽棵介!,它們依然是外部存儲吧史,也就是說4.4系統(tǒng)及以上的手機將機身存儲存儲(手機自身帶的存儲叫做機身存儲)在概念上分成了”內部存儲internal” 和”外部存儲external” 兩部分邮辽。既然16G,32G是外部存儲贸营,那有人又有疑惑了吨述,那4.4系統(tǒng)及以上的手機要是插了SD卡呢,SD卡又是什么呢钞脂,如果SD卡也是外部存儲的話揣云,那怎么區(qū)分機身存儲的外部存儲跟SD卡的外部存儲呢?對冰啃,SD卡也是外部存儲邓夕,那怎么區(qū)分呢,在4.4以后的系統(tǒng)中阎毅,API提供了這樣一個方法來遍歷手機的外部存儲路徑:
File[] files;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
files = getExternalFilesDirs(Environment.MEDIA_MOUNTED);
for(File file:files){
Log.e("main",file);
}
}
如果你的手機插了SD卡的話焚刚,那么它打印的路徑就有兩條了,例如我的華為榮耀7插了SD卡扇调,它的結果如下:
/storage/emulated/0/Android/data/packname/files/mounted
/storage/B3E4-1711/Android/data/packname/files/mounted
其中/storage/emulated/0目錄就是機身存儲的外部存儲路徑
而/storage/B3E4-1711/就是SD卡的路徑
他們統(tǒng)稱為外部存儲
訪問外部存儲的API方法:
1矿咕、Environment.getExternalStorageDirectory().getAbsolutePath()
2、Environment.getExternalStoragePublicDirectory(“”).getAbsolutePath()
3、getExternalFilesDir(“”).getAbsolutePath()
4碳柱、getExternalCacheDir().getAbsolutePath()
大家對Android的外部存儲會產(chǎn)生疑問捡絮,主要是現(xiàn)在很多的手機已經(jīng)從物理上看不到外部存儲了,以前的手機都有莲镣,就是那種黑色的內存卡福稳,8G,16G剥悟,32G的灵寺,可以像U盤一樣插拔曼库,以前很流行区岗,存儲空間不夠了,就去買個內存卡(準確說是SD卡毁枯,說成內存卡又會引起誤解)回來慈缔,后來的手機比如現(xiàn)在我用的華為榮耀7,廠家已經(jīng)把機身存儲擴展到了16G了种玛,只是在存儲概念上了分為了內部存儲(內部internal)和外部存儲(外部external)藐鹤,其實它們都集成在一起了。當然如果你覺得16G不夠用赂韵,那他支持通過插SD卡來擴充容量嗎娱节?支持的,榮耀7為例祭示,它是三合二卡槽肄满。卡槽1:Nano SIM卡质涛;卡槽2:Nano SIM卡或Micro SD卡稠歉。默認卡槽1為4G主卡,可以在設置中更改4G主卡卡槽汇陆;不支持熱插拔怒炸,插拔卡托后需重啟手機。這樣插入的SD卡也屬于外部存儲毡代。所以手機的外部存儲可能包含兩部分阅羹,一是機身存儲的外部存儲部分,還有一個是SD卡部分
二教寂、不同Android版本下getDataDirectory灯蝴,getFilesDir,getCacheDir孝宗,getDir穷躁,getExternalStorageDirectory,getExternalStoragePublicDirectory,getExternalFilesDir问潭,getExternalCacheDir猿诸,getExternalCacheDir,getRootDirectory的區(qū)別和聯(lián)系
上面這些方法狡忙,我們可能似曾相識梳虽,但是對于有些同學來說卻又很難分清出,主要還是不同的Android版本的問題灾茁。為了方便大家理解窜觉,我先簡要介紹以上各個方法,為方便大家理解我把這些方法的結果打印出來(以下的打印結果是基于榮耀7的(系統(tǒng)版本6.0):
1北专、Environment.getDataDirectory() = /data
這個方法是獲取內部存儲的根路徑
2禀挫、getFilesDir().getAbsolutePath() = /data/user/0/packname/files
這個方法是獲取某個應用在內部存儲中的files路徑
3、getCacheDir().getAbsolutePath() = /data/user/0/packname/cache
這個方法是獲取某個應用在內部存儲中的cache路徑
4拓颓、getDir(“myFile”, MODE_PRIVATE).getAbsolutePath() = /data/user/0/packname/app_myFile
這個方法是獲取某個應用在內部存儲中的自定義路徑
方法2,3,4的路徑中都帶有包名语婴,說明他們是屬于某個應用
…………………………………………………………………………………………
5、Environment.getExternalStorageDirectory().getAbsolutePath() = /storage/emulated/0
這個方法是獲取外部存儲的根路徑
6驶睦、Environment.getExternalStoragePublicDirectory(“”).getAbsolutePath() = /storage/emulated/0
這個方法是獲取外部存儲的根路徑
7砰左、getExternalFilesDir(“”).getAbsolutePath() = /storage/emulated/0/Android/data/packname/files
這個方法是獲取某個應用在外部存儲中的files路徑
8、getExternalCacheDir().getAbsolutePath() = /storage/emulated/0/Android/data/packname/cache
這個方法是獲取某個應用在外部存儲中的cache路徑
注意:其中方法7和方法8如果在4.4以前的系統(tǒng)中getExternalFilesDir(“”)和getExternalCacheDir()將返回null场航,如果是4.4及以上的系統(tǒng)才會返回上面的結果缠导,也即4.4以前的系統(tǒng)沒插SD卡的話,就沒有外部存儲溉痢,它的SD卡就等于外部存儲僻造;而4.4及以后的系統(tǒng)外部存儲包括兩部分,getExternalFilesDir(“”)和getExternalCacheDir()獲取的是機身存儲的外部存儲部分适室,也即4.4及以后的系統(tǒng)你不插SD卡嫡意,它也有外部存儲,既然getExternalFilesDir(“”)和getExternalCacheDir()獲取的是機身存儲的外部存儲部分捣辆,那么怎么獲取SD卡的存儲路徑呢蔬螟,還是通過上面提到的getExternalFilesDirs(Environment.MEDIA_MOUNTED)方法來獲取了,不知道Android有沒有提供相關的API接口來獲取SD卡的存儲路徑汽畴,大家可以去查資料旧巾。又重復了上面的話,主要是提醒大家要注意不同的Android版本是有差別的忍些,這個最坑了鲁猩。
…………………………………………………………………………………………
Environment.getDownloadCacheDirectory() = /cache
Environment.getRootDirectory() = /system
這兩個方法沒什么說的了,每個版本的android系統(tǒng)都一樣
…………………………………………………………………………………………
從上面我們很清楚的可以看到上面的方法可以分為三類罢坝,我用橫線隔開了廓握。第一類是位于根目錄/data下;還有一類是位于根目錄/storage下,可以看到調用它們的API方法都帶了一個External隙券;另外一類不在/data下也不再/storage下男应,比如系統(tǒng)文件/system,或者緩存文件/cache娱仔。
/data目錄下的文件物理上存放在我們通常所說的內部存儲里面
/storage目錄下的文件物理上存放在我們通常所說的外部存儲里面
/system用于存放系統(tǒng)文件沐飘,/cache用于存放一些緩存文件,物理上它們也是存放在內部存儲里面的
下面來看一下大家常見的疑問
疑問1牲迫、那getFilesDir().getAbsolutePath()和getCacheDir().getAbsolutePath()有什么區(qū)別呢耐朴?
其實是沒有什么區(qū)別的,我們可以看下面一張圖:
getFilesDir獲取的是files目錄,getCacheDir獲取的是cache目錄,它們位于同一級目錄裸准,只是為了用來存放不同類型的數(shù)據(jù)的,由文件名不難看出:cache下存放緩存數(shù)據(jù)蜒滩,databases下存放使用SQLite存儲的數(shù)據(jù)滨达,files下存放普通數(shù)據(jù)(log數(shù)據(jù)奶稠,json型數(shù)據(jù)等),shared_prefs下存放使用SharedPreference存放的數(shù)據(jù)捡遍。這些文件夾都是由系統(tǒng)創(chuàng)建的锌订。
疑問2、getFilesDir().getAbsolutePath()和getExternalFilesDir(“”).getAbsolutePath()有什么區(qū)別呢画株?
我們先看它們的路徑:
/data/user/0/packname/files
/storage/emulated/0/Android/data/packname/files
很顯然這兩個的區(qū)別是一個在內部存儲里面辆飘,一個在外部存儲里面,這是它們的區(qū)別谓传。它們的共同點呢蜈项,就是它們的路徑都帶有包名,表明是這個APP的專屬文件续挟,這類文件應該是隨著app卸載而一起被刪除的紧卒,并且我們在設置里面清除該應用的數(shù)據(jù)時,這兩個文件夾下的數(shù)據(jù)都會被清除诗祸。
疑問3跑芳、什么是APP專屬文件?
上面疑問2我們提到了專屬文件直颅,所謂專屬文件就是它是屬于某個具體的應用的博个,他的文件路徑都帶有相應的包名,當APP卸載時功偿,它們會隨應用一起刪除盆佣,當我們在設置里面手動清除某個應用數(shù)據(jù)時(不是清除緩存),它們也會一起被清掉。Android使用這種專屬文件的目的就是為了方便文件管理共耍,避免文件隨意存儲投蝉,顯得很亂,另一個目的就是為了當應用被卸載時不會留下很多垃圾文件征堪。
疑問4瘩缆、既然內部存儲與外部存儲都有APP專屬文件,那么我們該使用哪個呢佃蚜?
內部存儲與外部存儲都有APP專屬文件庸娱,我們該用哪個呢,很顯然應該用外部存儲的谐算,因為內部存儲本身就比較小熟尉,而且已經(jīng)存儲了一些系統(tǒng)的文件,因此內部存儲我們盡量不要去使用洲脂。但是當手機沒有外部存儲時斤儿,我們還是得使用內部存儲,一般程序員會做判斷是否有外部存儲恐锦,沒有再使用內部存儲往果,代碼如下:
public static String getFilePath(Context context,String dir) {
String directoryPath="";
if (MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ) {//判斷外部存儲是否可用
directoryPath =context.getExternalFilesDir(dir).getAbsolutePath();
}else{//沒外部存儲就使用內部存儲
directoryPath=context.getFilesDir()+File.separator+dir;
}
File file = new File(directoryPath);
if(!file.exists()){//判斷文件目錄是否存在
file.mkdirs();
}
return directoryPath;
}
為了讓大家更好地理解不同版本的Android系統(tǒng)的存儲差異我做了下列一份說明表:
比較的是我向getFilesDir().getAbsolutePath()路徑下和getExternalFilesDir(“”).getAbsolutePath()路徑各寫入19.48M數(shù)據(jù)前后的差別
表一、4.1.1系統(tǒng)一铅,帶有SD卡 (真機)
存儲位置 | 獲取路徑的方法 | 容量(寫入前) | 容量(寫入后) | 備注 |
---|---|---|---|---|
/data/data/packname/files | getFilesDir() | 1.59GB | 1.57GB | 內部存儲 |
/storage/sdcard0/Android | ||||
/data/packname/files | getExternal | |||
StorageDirectory() | 1.47GB | 1.45GB | 外部存儲(SD卡) |
表二陕贮、4.1.1系統(tǒng),不帶有SD卡 (真機)
存儲位置 | 獲取路徑的方法 | 容量(寫入前) | 容量(寫入后) | 備注 |
---|---|---|---|---|
/data/data/packname/files | getFilesDir() | 1.59GB | 1.47GB | 內部存儲 |
路徑不存在 | getExternal | |||
StorageDirectory() | ~~~ | ~~~ | 沒插SD卡 |
表三潘飘、4.2.1系統(tǒng)肮之,帶有SD卡 (模擬器)
存儲位置 | 獲取路徑的方法 | 容量(寫入前) | 容量(寫入后) | 備注 |
---|---|---|---|---|
/data/data/packname/files | getFilesDir() | 1.85GB | 1.83GB | 內部存儲 |
/mnt/sdcard/Android | ||||
/data/packname/files | getExternal | |||
StorageDirectory() | 98.42MB | 78.93MB | 外部存儲(SD卡) |
表四、4.4.2系統(tǒng)卜录,帶有SD卡 (真機)
存儲位置 | 獲取路徑的方法 | 容量(寫入前) | 容量(寫入后) | 備注 |
---|---|---|---|---|
/data/data/packname/files | getFilesDir() | 2.22GB | 2.18GB | 內部存儲 |
/storage/emulated/0/Android | ||||
/data/packname/files | getExternal | |||
StorageDirectory() | 2.20GB | 2.16GB | 機身外部存儲 | |
/storage/sdcard1 | getExternalFilesDirs | 1.47GB | 1.47GB | 外部存儲(SD卡 |
沒有向其寫數(shù)據(jù)戈擒,只是讀取) |
表五艰毒、4.4.2系統(tǒng)筐高,不帶有SD卡 (真機)
存儲位置 | 獲取路徑的方法 | 容量(寫入前) | 容量(寫入后) | 備注 |
---|---|---|---|---|
/data/data/packname/files | getFilesDir() | 2.22GB | 2.18GB | 內部存儲 |
/storage/emulated/0/Android | ||||
/data/packname/files | getExternal | |||
StorageDirectory() | 2.20GB | 2.16GB | 機身外部存儲 |
表六、6.0.0系統(tǒng)现喳,帶有SD卡 (真機)
存儲位置 | 獲取路徑的方法 | 容量(寫入前) | 容量(寫入后) | 備注 |
---|---|---|---|---|
/data/user/0/packname/files | getFilesDir() | 11.94GB | 11.90GB | 內部存儲 |
/storage/emulated/0/Android | ||||
/data/packname/files | getExternal | |||
StorageDirectory() | 11.92GB | 11.88GB | 機身外部存儲 | |
/storage/B3E4-1711 | getExternalFilesDirs | 1.47GB | 1.47GB | 外部存儲(SD卡) |
沒有向其寫數(shù)據(jù)凯傲,只是讀取 |
表七、6.0.0系統(tǒng)嗦篱,不帶有SD卡 (真機)
存儲位置 | 獲取路徑的方法 | 容量(寫入前) | /storage/容量(寫入后) | 備注 |
---|---|---|---|---|
/data/user/0/packname/files | getFilesDir() | 11.93GB | 11.89GB | 內部存儲 |
/storage/emulated/0/Android | ||||
/data/packname/files | getExternal | |||
StorageDirectory() | 11.91GB | 11.87GB | 機身外部存儲 |
注:上述容量指的是該路徑所在根路徑的可用容量冰单,比如/data/data/packname/files的容量是指/data的可用容量,/storage/sdcard0/Android/data/packname/files指的是/storage/sdcard0的可用容量灸促,而一般在4.4及以上的系統(tǒng)中诫欠,我們很少操作SD
三涵卵、清除數(shù)據(jù)和清除緩存到底清除了什么數(shù)據(jù)
這個很容易搞混,為什么呢荒叼?通過上面我們知道:
/data/user/0/packname/files它是用來存儲普通數(shù)據(jù)的
/data/user/0/packname/cache它是用來存儲緩存數(shù)據(jù)的
所以很多人就以為我清除數(shù)據(jù)時清除的肯定就是files下的數(shù)據(jù)轿偎,而我清除緩存數(shù)據(jù)時清除的肯定就是cache下的數(shù)據(jù),但是事實卻不是這樣的被廓。正確應該是:
清除緩存:我們知道應用程序在運行過程中需要經(jīng)過很多過程坏晦,比如讀入程序,計算嫁乘,輸入輸出等等昆婿,這些過程中肯定會產(chǎn)生很多的數(shù)據(jù),它們在內存中蜓斧,以供程序運行時調用仓蛆。所以清除緩存清除的是APP運行過程中所產(chǎn)生的臨時數(shù)據(jù)。
清除數(shù)據(jù):清除數(shù)據(jù)才是真正的刪除了我們保存在文件中的數(shù)據(jù)(永久性數(shù)據(jù)挎春,如果不人為刪除的話會一直保存在文件中)例如當我們在設置里面清除了某個應用的數(shù)據(jù)看疙,那么/data/user/0/packname/和/storage/emulated/0/Android/data/packname/下的文件里面的數(shù)據(jù)會全部刪除,包括cache直奋,files能庆,lib,shared_prefs等等帮碰。
四相味、/storage/sdcard拾积,/sdcard殉挽,/mnt/sdcard,/storage/emulated/0之間的關系
從上面的表中我們可以發(fā)現(xiàn)拓巧,在4.1系統(tǒng)中斯碌,getExternalStorageDirectory方法獲取到的路徑為/storage/sdcard0;4.2系統(tǒng)中getExternalStorageDirectory方法獲取到的路徑為/mnt/sdcard肛度,因為4.2是模擬器打印的結果傻唾,如果是真機的話也是/storage/sdcard0;4.4的getExternalStorageDirectory方法獲取到的路徑為/storage/emulated/0承耿,它的SD卡存儲路徑為/storage/sdcard1冠骄;6.0的getExternalStorageDirectory方法獲取到的路徑為/storage/emulated/0,它的SD卡存儲路徑為/storage/B3E4-1711加袋;另外根據(jù)測試在4.0上getExternalStorageDirectory方法獲取到的路徑為/mnt/sdcard凛辣。所以在真機上,getExternalStorageDirectory獲取到的路徑如下表所示:
系統(tǒng)版本 | 結果 |
---|---|
4.0 | /mnt/sdcard |
4.1 | /storage/sdcard0 |
4.2 | /storage/sdcard0 |
4.4 | /storage/emulated/0 |
6.0 | /storage/emulated/0 |
要理解/storage/sdcard职烧,/sdcard扁誓,/mnt/sdcard防泵,/storage/emulated/0之間的關系,我們需要先要了解一下linux文件掛載的概念蝗敢,關于掛載大家可以自行去百度捷泞。還有我們不明白為什么會有有/storage/sdcard,/sdcard寿谴,/mnt/sdcard锁右,/storage/emulated/0這么多目錄,讓人看起來眼花繚亂讶泰,要詳細了解請仔細看下面的文章骡湖,下面的文章是我摘自關于android的4.2的0文件夾的詳解
—- android 4.0 —-
在galaxy nexus(GN)手機上userdata分區(qū)很大,被掛在/data目錄峻厚,用戶的數(shù)據(jù)通常是放在sd卡上响蕴,然而gn是沒有sd卡的,所以google想了一個辦法惠桃,就是虛擬一個浦夷。
所以,在userdata分區(qū)下有個目錄叫media辜王,是內置sd卡的數(shù)據(jù)存儲位置劈狐,使用fuse技術將/data/media虛擬成為一個叫做/dev/fuse的設備,為了讓程序能認出來呐馆,被同時掛載在 /mnt/sdcard 目錄肥缔,又為了兼容以前的程序,做了一個快捷方式(linux系統(tǒng)里叫軟連接) /sdcard 指向的是 /mnt/sdcard .
當然汹来,這些都是4.0的做法续膳。
—- android 4.1 —-
在4.1里,同樣也會使用fuse技術收班,/dev/fuse 會被同時掛載到/storage/sdcard0 目錄坟岔,這個sdcard0表示第一個sd卡(如果有外置sd卡,那會多一個 /storage/sdcard1摔桦,比如我的xoom)社付, /sdcard 軟連接會指向 /storage/sdcard0 ,此時/mnt/sdcard 也是個軟連接邻耕,會指向/storage/sdcard0鸥咖。
如果你通過otg線接U盤,會被掛載到 /storage/usb0目錄兄世,stickmount這個軟件為了讓圖庫啼辣、快圖、mx player等軟件碘饼,能看到u盤里的數(shù)據(jù)熙兔,又同時掛載到 /storage/sdcard0/usStorage/sda1.
也許你會問悲伶,為什么不是usb0,而是sda1住涉,這是linux的對硬盤的命名方式麸锉,如果你的u盤有多個分區(qū),就分別是sda1,sda2這樣一直排下去了舆声。
—- android 4.2 —-
好了花沉,我們開始說4.2系統(tǒng)。
谷歌是不是沒事干啊媳握,非要給android搞個多用戶碱屁,你想想啊,在中國蛾找,可能因為經(jīng)濟問題娩脾,家里不是每人一個電腦,在美國打毛,幾乎需要用電腦的人柿赊,都會自己有一臺或多臺,一臺電腦多人用的情況少之又少幻枉,這就是為什么叫PC了碰声,顧名思義,個人電腦熬甫。像手機和平板這些東西胰挑,更加私人化了,很少公用了吧椿肩,我想在中國也是如此吧瞻颂。
當然,谷歌也不完全是抽風覆旱,因為他有更大的戰(zhàn)略部署蘸朋,而且平板也的確有多人用的可能。
所以谷歌搞出來一個多用戶扣唱,那每個人的應用、數(shù)據(jù)团南、個性配置都要分開吧噪沙。 應用和個性配置好弄,想想啊吐根,通過權限控制正歼,每人只能看自己的應用就行了,桌面也可以用自己的拷橘。
那數(shù)據(jù)怎么辦局义?喜爷??萄唇?
好吧檩帐,調整用戶數(shù)據(jù)的掛載結構。android 4.2另萤,同樣也會使用fuse技術/dev/fuse 會被掛載到/storage/emulated/0 目錄湃密,為什么是0呢,你還記得上邊的sdcard0吧四敞,第一個的意思泛源。(如果有第二個,應該就是/storage/emulated/1忿危,我們的三兒子沒有外置sd卡达箍,所以沒法驗證)
為了兼容以前,同時掛載到 /storage/emulated/legacy (故名思議铺厨,傳統(tǒng)的)幻梯,還建立三個軟連接 /storage/sdcard0 ,/sdcard努释,/mnt/sdcard 碘梢,都指向 /storage/emulated/legacy
很多同學可能不會認真看上面,這里我就簡單總結一下:
1伐蒂、其中sdcard/煞躬、mnt/sdcard、storage/sdcard0逸邦、storage/emulated/0恩沛、storage/emulated/legacy都是同一個路徑的不同”指針“,指向的是同一個地方缕减,只是不同Android版本的叫法不一樣雷客。
2、如果大家想了解每個版本的外部存儲路徑桥狡,同學們可以通過獲取getExternalStorageDirectory方法的打印結果進行對比
五搅裙、一張圖看懂Ram,Rom裹芝,以及擴展存儲(TF卡)的區(qū)別部逮;內部存儲,外部存儲的區(qū)別嫂易。
1兄朋、首先我們來弄清幾個概念,內存怜械,內部存儲颅和,外部存儲傅事,機身存儲(內置存儲)。
1.1內存峡扩;我們在英文中稱作memory蹭越,內存是計算機中重要的部件之一,它是與CPU進行溝通的橋梁有额。計算機中所有程序的運行都是在內存中進行的般又,所以說它是用于計算機運行時的,它不是用來存儲數(shù)據(jù)的巍佑。
1.2內部存儲茴迁,外部存儲;內部存儲我們稱為InternalStorage萤衰,外部我們稱為ExternalStorage堕义,這兩個概念來自于早期的Android智能機,4.4以前脆栋,內置存儲就是內部存儲倦卖,外置SD卡就是外置存儲。我們通過getDataDirectory就可以獲取內置存儲根路徑椿争,通過getExternalStorageDirectory就可以獲取外置SD卡根路徑怕膛。4.4以后外部存儲就包含兩部分了,其中通過getExternalStorageDirectory獲取的是機身存儲的外部存儲秦踪,而外置SD卡我們則需要通過getExternalDirs遍歷來獲取了褐捻。
1.3機身存儲;機身存儲是指手機自身攜帶的存儲空間椅邓,出廠時就已經(jīng)有了柠逞,4.4以前機身存儲就是內部存儲,4.4及以后機身存儲包含了內部存儲和外部存儲景馁。
2板壮、Ram,Rom合住,以及擴展存儲(TF卡)的概念绰精。從圖中我們可以看到,一個手機里面有內存聊疲,手機內置存儲茬底,以及SD卡, 它們分別是Ram获洲,Rom,以及TF卡殿如,這三種卡的性能贡珊,材質及價格都不一樣最爬,都有各自的用處。
3门岔、內部存儲爱致,外部存儲的概念。很多人對這個存在誤解寒随,認為機身存儲就是內存糠悯,而SD卡才叫外部存儲,這其實是不對的妻往,不同的Android版本是有差別的互艾,請看第1條。
最后附上我的例子:
http://download.csdn.net/download/u010937230/9930396