Android儲存
一、基本認識
所有的Android裝置都有兩個檔案儲存區域:“內部”和“外部”儲存。這兩個名稱來自早期的Android,當時大多數裝置都提供內建的固定的記憶體(內部儲存)即ROM(主要分三部分:系統儲存、系統快取、內部儲存)中的內部儲存部分,外加一個可移動的儲存介質,如SD卡(外部儲存)。現在的大部分裝置把固定不變的儲存空間分成“內部”和“外部”兩部分,這樣即使沒有可移動的儲存介質,也總會有兩個儲存空間,並且不管外部儲存器是可移動的,還是固定的,API的行為是相同的。
把手機連線電腦,能被電腦識別的部分就一定是外部儲存。
開啟DDMS,有一個File Explorer,如下:
這裡有三個資料夾需要我們重視,一個是data,一個是mnt,一個是storage,我們下面就詳細說說這三個資料夾。
1、記憶體(Memory)
RAM(隨機訪問儲存器),斷電後資料丟失。
2、內部儲存(InternalStorage)
data資料夾就是內部儲存,應用程式私有的,其他應用無法訪問。當我們開啟data資料夾之後(沒有root的手機不能開啟該資料夾),裡邊有兩個資料夾值得我們關注,如下:
app資料夾:存放著我們所有安裝的app的apk檔案。當我們除錯一個app的時候,可以看到控制檯輸出的內容,有一項是uploading……就是上傳我們的apk到這個資料夾,上傳成功之後才開始安裝。
data資料夾:這個資料夾裡邊都是一些包名,開啟這些包名之後我們會看到這樣的一些檔案:
- /data/data/包名/shared_prefs
- /data/data/包名/databases
- /data/data/包名/files
- /data/data/包名/cache
在使用sharedPreferenced的時候,將資料持久化儲存於本地,就是將xml檔案儲存於shared_prefs資料夾;App裡邊的資料庫檔案就儲存於databases資料夾中;普通資料儲存在files中;快取檔案儲存在cache資料夾中。
方法
-
Environment.getDataDirectory()
/data -
context.getFilesDir()
/data/data/包名/files -
context.getCacheDir()
/data/data/包名/cache,機身記憶體不足時,檔案會被刪除
3、外部儲存(ExternalStorage)
任何有訪問許可權的應用均可以訪問修改,相對於裝置的內部儲存空間而言,會大很多,所以一般比較大的資料,均會存放在外部儲存中。寫入資料,你必須在清單檔案中申請WRITE_EXTERNAL_STORAGE許可權和READ_EXTERNAL_STORAGE(API 19開始,不再需要顯式宣告這兩個許可權,除非要讀寫其他應用的應用資料)。外部儲存一般就是我們上面看到的storage資料夾,當然也有可能是mnt檔案夾,這個不同廠家有可能不一樣。
一般來說,在storage資料夾中有一個sdcard資料夾,這個資料夾中的檔案又分為兩類,一類是公有目錄,還有一類是私有目錄,其中的公有目錄有九大類,比如DCIM、DOWNLOAD等這種系統為我們建立的資料夾,私有目錄就是Android這個資料夾,這個資料夾開啟之後裡邊有一個data資料夾,開啟這個data資料夾,裡邊有許多包名組成的資料夾(也可以被其他應用修改)。
建議App的資料應該儲存在外部儲存的私有目錄中該app的包名下,這樣當使用者解除安裝掉App之後,相關的資料會一併刪除,這樣有利於系統維護,也避免使用者的反感。如果你直接在/storage/sdcard目錄下建立了一個應用的資料夾,那麼當你刪除應用的時候,這個資料夾就不會被刪除。不建議往內部儲存中寫太多的資料,畢竟空間有限。
按照路徑的特徵,又可以將檔案儲存的路徑分為兩大類:路徑中含有包名的;路徑中不含有包名的。含有包名的路徑,因為和某個App有關,所以對這些資料夾的訪問都是呼叫Context裡邊的方法,而不含有包名的路徑,和某一個App無關,可以通過Environment中的方法來訪問。
開啟手機設定,選擇應用管理,選擇任意一個App,然後你會看到兩個按鈕,一個是清除快取,另一個是清除資料。清除資料清除的是內部儲存目錄中相應的files和cache資料夾中的檔案和外部儲存中相應的files和cache資料夾中的檔案。
方法:
-
Environment.getExternalStorageState() String
獲取SD卡狀態,Environment.MEDIA_MOUNTED為可用 -
Environment.getExternalStorageDirectory()
獲取外部儲存根目錄(/storage/sdcard0) -
Environment.getExternalStoragePublicDirectory("folder1")
/storage/sdcard0/folder1 -
Environment.getExternalStoragePublicDirectory(String type)
訪問公有九大目錄 -
File getExternalFilesDir(String type)
/storage/sdcard/Android/包名/files -
File getExternalCacheDir()
/storage/sdcard/Android/包名/cache -
getExternalFilesDir(null)
/storage/Android/data/包名/files -
getExternalFilesDir("caches")
/storage/Android/data/包名/files/caches,當空間不足時,檔案不會實時被刪除,可能返回空物件
type型別:
值 | 文字 |
---|---|
Environment.DIRECTORY_NOTIFICATIONS | Notifications |
Environment.DIRECTORY_PODCASTS | Podcasts |
Environment.DIRECTORY_RINGTONES | Ringtones |
Environment.DIRECTORY_ALARMS | Alarms |
Environment.DIRECTORY_PICTURES | Pictures |
Environment.DIRECTORY_MOVIES | Movies |
Environment.DIRECTORY_DOWNLOADS | Download |
Environment.Environment.DIRECTORY_DCIM | DCIM |
Environment.DIRECTORY_DOCUMENTS | Documents |
二、StatFs
用於獲取儲存空間
- 建構函式
StatFs(String filePath)
API<18
-
getAvailableBlocks()
檔案系統中可被應用程式使用的空閒儲存區塊的數量 -
getBlockCount()
檔案系統中總的儲存區塊的數量 -
getBlockSize()
檔案系統中每個儲存區塊的位元組數 -
getFreeBlocks()
檔案系統中總的空閒儲存區塊的數量,包括保留的儲存區塊(不能被普通應用程式使用)
API>=18
-
getAvailableBlocksLong()
檔案系統中可被應用程式使用的空閒儲存區塊的數量 -
getAvailableBytes()
檔案系統中可被應用程式使用的空閒位元組數 -
getBlockCountLong()
檔案系統中總的儲存區塊的數量 -
getBlockSizeLong()
檔案系統中每個儲存區塊的位元組數 -
getFreeBlocksLong()
檔案系統中總的空閒儲存區塊的數量,包括保留的儲存區塊(不能被普通應用程式使用) -
getFreeBytes()
檔案系統中總的空閒位元組數,包括保留的儲存區塊(不能被普通應用程式使用) -
getTotalBytes()
檔案系統支援的總的儲存位元組數
獲取SD卡的完整空間大小,返回MB
StatFs fs = new StatFs(getSDCardBaseDir());
long count = fs.getBlockCountLong();
long size = fs.getBlockSizeLong();
return count * size / 1024 / 1024;
往SD卡的公有目錄下儲存檔案
public static boolean saveFileToSDCardPublicDir(byte[] data, String type, String fileName) {
BufferedOutputStream bos = null;
if (isSDCardMounted()) {
File file = Environment.getExternalStoragePublicDirectory(type);
try {
bos = new BufferedOutputStream(new FileOutputStream(new File(file, fileName)));
bos.write(data);
bos.flush();
return true;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
從SD卡獲取檔案
public static byte[] loadFileFromSDCard(String fileDir) {
BufferedInputStream bis = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
bis = new BufferedInputStream(new FileInputStream(new File(fileDir)));
byte[] buffer = new byte[8 * 1024];
int c = 0;
while ((c = bis.read(buffer)) != -1) {
baos.write(buffer, 0, c);
baos.flush();
}
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
baos.close();
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
參考文獻:
徹底理解android中的內部儲存與外部儲存
是時候弄清楚getExternalStorageDirectory()和getExternalFilesDir()的區別了
Android檔案儲存使用參考 - liaohuqiu
相關文章
- Android儲存(2)– 介面卡儲存Android
- Android 外部儲存Android
- android 儲存方式Android
- Android-內部儲存和外部儲存Android
- Android 資料儲存知識梳理(2) Android儲存目錄Android
- Android內部儲存和外部儲存,以及讀取Android讀取RAM,ROM內部儲存和外部儲存卡容量Android
- Android 檔案儲存Android
- android: 檔案儲存Android
- android: SharedPreferences儲存Android
- Android 儲存概覽Android
- Android中的資料儲存之檔案儲存Android
- Android資料儲存之SharedPreferences及如何安全儲存Android
- Android儲存之SharedPreferencesAndroid
- Android的3種資料儲存技術(一)File儲存Android
- Android 檔案儲存淺析Android
- Android儲存(3)– 裝置配置Android
- android SAF儲存訪問框架Android框架
- Android WebView儲存Cookie登入AndroidWebViewCookie
- Android中的資料儲存Android
- 33.Android資料儲存Android
- Android——儲存圖片到外部儲存並進行原生分享Android
- Android的儲存----重新認識Android(9)Android
- 【usb儲存掛載】android6.0固定usb儲存掛載路徑Android
- Android從外部儲存裝置中儲存和載入本地檔案Android
- 塊儲存 檔案儲存 物件儲存物件
- Android儲存多張圖片到本地Android
- 淺談Android的檔案儲存Android
- Android本地儲存的幾種方式Android
- Android儲存讀取txt檔案Android
- Android中資料儲存之SharedPreferencesAndroid
- Android 元件系列-----Activity儲存狀態Android元件
- Android資料儲存之Android 6.0執行時許可權下檔案儲存的思考Android
- Android Room 之儲存 Objects 中的 ListAndroidOOMObject
- Android 儲存優化 —— MMKV 整合與原理Android優化
- 快速理解Android檔案儲存路徑Android
- 詳解Android資料儲存技術Android
- Android中資料儲存的方式有哪些Android
- Android 儲存系統之原始碼篇Android原始碼