Android的存儲空間分為內部存儲和外部存儲兩種. 需要注意的是, 無論Android手機有沒有SD卡, 內部存儲和外部存儲都是存在的.
內部存儲
內部存儲空間十分有限, 是Android系統本身和系統應用程序主要的數據存儲所在地, 一旦內部存儲空間耗盡, 手機也就無法使用了. 我們應該盡量避免在編碼時使用內部存儲空間.
/*
* 私有目錄結構:
* 1.模擬器
* /data/user/0/包名/cache
* /data/user/0/包名/code_cache
* /data/user/0/包名/databases
* /data/user/0/包名/shared_prefs
* /data/user/0/包名/files
*
* 2.真機
* /data/data/包名/lib
* /data/data/包名/cache
* /data/data/包名/databases
* /data/data/包名/files
* /data/data/包名/shared_prefs
*
* Google官方建議我們將App的數據存儲在外部存儲的私有目錄中該App的包名下,
* 當用戶卸載App后, 這些數據會一并刪除.
*/
App的Database
, SharedPreference
,Cache
等文件都保存在內部存儲中.
Android提供了兩個方法來訪問內部存儲空間:
context.getFilesDir(); // /data/data/包名/files
context.getCacheDir(); // /data/data/包名/cache
外部存儲
外部存儲和SD卡沒有必然的聯系, 這里有一個簡單的方法區分外部存儲和內部存儲:
手機連接上電腦, 能被電腦識別的部分就一定是外部存儲。
外部存儲還被分成應用私有目錄和公有目錄. 保存在應用私有目錄下的文件會在應用被卸載的同時被刪除.
私有目錄
/storage/emulated/0/Android/data/包名/
建議將App運行過程中產生的文件放入應用私有目錄下, 當App卸載后, 私有目錄下的文件也會隨之刪除. 如果不希望文件在App卸載后被刪除, 可以將其放入公有目錄下.
公有目錄
外部存儲中私有目錄之外的都是公有目錄.
參考資料:
1.Android中的文件操作詳解以及內部存儲和外部存儲
2.徹底了解Android中的內部存儲與外部存儲
最后放上一個比較全的Android文件操作工具類吧, 光講沒啥印象, 還是多寫代碼, 理解才深刻.
package com.hfut.zhaojiabao.myrecord.utils;
import android.content.Context;
import android.os.Environment;
import android.os.StatFs;
import java.io.File;
/**
* @author zhaojiabao (zhaojiabao@huami.com)
*/
public class FileUtil {
/*
* 私有目錄結構:
* 1.模擬器
* /data/user/0/包名/cache
* /data/user/0/包名/code_cache
* /data/user/0/包名/databases
* /data/user/0/包名/shared_prefs
* /data/user/0/包名/files
*
* 2.真機
* /data/data/包名/lib
* /data/data/包名/cache
* /data/data/包名/databases
* /data/data/包名/files
* /data/data/包名/shared_prefs
*
* Google官方建議我們將App的數據存儲在外部存儲的私有目錄中該App的包名下,
* 當用戶卸載App后, 這些數據會一并刪除.
*/
/*----------------------------內部存儲----------------------------*/
/**
* 獲取應用私有目錄
* /data/data/包名/files
* 或
* /data/user/0/包名/files
*/
public static File getFilesDir(Context context) {
return context.getFilesDir();
}
/**
* 獲取應用緩存目錄
* /data/data/包名/cache
* 或
* /data/user/0/包名/cache
*/
public static File getCacheDir(Context context) {
return context.getCacheDir();
}
/**
* 獲取內部存儲根目錄
* /data
*/
public static File getInternalRootDir() {
return Environment.getDataDirectory();
}
/**
* 獲取內部存儲下載目錄
* /data/cache
*/
public static File getInternalDownloadDir() {
return Environment.getDownloadCacheDirectory();
}
/*----------------------------內部存儲----------------------------*/
/**
* 獲取應用在外部存儲的私有目錄下的文件目錄
* /storage/emulated/0/Android/data/包名/files/目錄名
* 目錄名可以選擇Environment中的多個常量
*/
public static File getAppExternalDir(Context context, String dir) {
return context.getExternalFilesDir(dir);
}
/**
* 獲取應用在外部存儲的私有目錄下的緩存目錄
* storage/emulated/0/Android/data/包名/cache
*/
public static File getAppCacheDir(Context context) {
return context.getExternalCacheDir();
}
/**
* 獲取外部存儲根目錄
* /storage/emulated/0
*/
public static File getExternalRootDir() {
return Environment.getExternalStorageDirectory();
}
/**
* 獲取外部存儲指定目錄
* /storage/emulated/0/目錄名
*/
public static File getExternalDir(String dir) {
return Environment.getExternalStoragePublicDirectory(dir);
}
/**
* 判斷SD卡是否被掛載
*/
public static boolean isSDCardMounted() {
return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}
/**
* 獲取SD卡根目錄
*
* @return /storage/emulated/0
*/
public static String getSDCardBaseDir() {
if (isSDCardMounted()) {
return Environment.getExternalStorageDirectory().getAbsolutePath();
}
return null;
}
/**
* 獲取SD卡大小(MB), 若未掛載, 返回-1
*/
public static long getSDCardSize() {
if (isSDCardMounted()) {
StatFs statFs = new StatFs(getSDCardBaseDir());
long count = statFs.getBlockCountLong();
long size = statFs.getBlockSizeLong();
return count * size / 1024 / 1024;
}
return -1;
}
/**
* 獲取SD卡空閑空間大小(MB), 若未掛載, 返回-1
*/
public static long getSDCardFreeSize() {
if (isSDCardMounted()) {
StatFs statFs = new StatFs(getSDCardBaseDir());
long freeCount = statFs.getFreeBlocksLong();
long size = statFs.getBlockSizeLong();
return freeCount * size / 1024 / 1024;
}
return -1;
}
/**
* 獲取SD卡可用空間大小(MB), 若未掛載, 返回-1
*/
public static long getSDCardAvailableSize() {
if (isSDCardMounted()) {
StatFs statFs = new StatFs(getSDCardBaseDir());
long availableCount = statFs.getAvailableBlocksLong();
long size = statFs.getBlockSizeLong();
return availableCount * size / 1024 / 1024;
}
return -1;
}
}