Tips: 複製的源碼爲Java代碼,示例使用Kotlin編寫。
內部存儲
內部存儲可以直接在設備的內部存儲中保存文件。默認情況下,保存到內部存儲的文件是應用的私有文件,其他應用(和用戶)不能訪問這些文件。 當用戶卸載您的應用時,這些文件也會被移除。
- 返回內部存儲文件上目錄的絕對路徑,其中存儲了當前應用程序的所有私有文件。例:/data/user/0/應用包名
public abstract File getDataDir();
示例如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val mDataFilePath = applicationContext.dataDir
Log.e(javaClass.simpleName, mDataFilePath.path)
}
打印輸出: /data/user/0/應用包名
- 獲取當前應用在內部存儲上的根目錄,返回存儲在內部存儲上的文件目錄的絕對路徑。例:/data/user/0/應用包名/files
public abstract File getFilesDir();
示例如下:
// 獲取系統存儲上當前應用的根目錄文件
val mFileDir = activity!!.applicationContext.filesDir
// 打印系統存儲上當前應用的根目錄地址
Log.e(javaClass.simpleName, "根目錄:${mFileDir.path}")
// 在系統存儲上當前應用的根目錄下創建文件夾
val mRootFile = File(mFileDir, "content.txt")
// 打印系統存儲上當前應用的根目錄地址
Log.e(javaClass.simpleName, "文件地址:${mRootFile.path}")
// 此處省略調用代碼......
/**
* 向文件中寫入文本
* Kotlin在擴展函數use中已經封裝了關閉流,所以這裏不用再調流的close()方法
*/
private fun writeTextToFile(file: File) {
BufferedWriter(FileWriter(file)).use {
it.write("秦川小將")
}
}
/**
* 讀取文件中的文本內容
* Kotlin在擴展函數use中已經封裝了關閉流,所以這裏不用再調流的close()方法
*/
private fun readTextInFile(file: File) {
BufferedReader(FileReader(file)).use {
var mLine: String
while (true) {
mLine = it.readLine() ?: break
Log.e(javaClass.simpleName, mLine)
}
}
}
注: Kotlin在擴展函數use中已經封裝了關閉流,所以這裏不用再調流的close()方法。
打印輸出如下:
根目錄: /data/user/0/com.files.sample/files
文件地址:/data/user/0/com.files.sample/files/content.txt
秦川小將
- 檢索,創建需要的新目錄,應用程序可以在其中放置自己的自定義數據文件。例:/data/user/0/應用包名/自定義文件目錄名
public abstract File getDir(String name, @FileMode int mode);
mode參數取值說明,如下:
Context.MODE_PRIVATE
默認的方式,創建的文件只能被本Activity所訪問。Context.MODE_WORLD_READABLE
允許所有其他應用程序對創建的文件具有讀訪問權限,Android API 17以後不建議使用。從Android API 24嘗試使用此模式開始,將會拋出一個SecurityException異常。Context.MODE_WORLD_WRITEABLE
允許所有其他應用程序對創建的文件具有寫入權限。Android API LEVEL 17以後不建議使用。Context.MODE_APPEND
將內容以追加的方式寫到文件末尾。
示例如下:
val mFile = applicationContext.getDir("custom", Context.MODE_PRIVATE)
Log.e(javaClass.simpleName, mFile.path)
打印輸出:/data/user/0/com.files.sample/app_custom
- 返回當前應用在內部存儲上的緩存目錄的絕對路徑。例:/data/user/0/應用包名/cache
public abstract File getCacheDir();
示例如下:
val mFile = applicationContext.cacheDir
Log.e(javaClass.simpleName, mFile.path)
打印輸出: /data/user/0/com.files.sample/cache
外部存儲
外部存儲是有可能移除的存儲介質(例如 SD 卡)或不可移除存儲(設備自帶內存)。保存到外部存儲的文件是全局可讀取文件,而且,在計算機上啓用 USB 大容量存儲以傳輸文件後,可由用戶對這些文件進行修改。
存儲權限(Android v6.0需要動態申請)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
1.Environment提供的存儲路徑
- 系統根目錄,例:/system
public static File getRootDirectory()
- 返回用戶數據目錄,例:/data
public static File getDataDirectory()
- 返回下載/緩存內容目錄,例:/data/cache
public static File getDownloadCacheDirectory()
- 返回外部存儲目錄,例:/storage/emulated/0
public static File getExternalStorageDirectory()
打印 /storage/emulated/0 目錄下所有文件名
val mFiles = Environment.getExternalStorageDirectory()
mFiles.list().forEach {
Log.e(javaClass.simpleName, "${mFiles.path}/$it")
}
getExternalStorageDirectory 具體輸出:
/storage/emulated/0/MIUI
/storage/emulated/0/mipush
/storage/emulated/0/sogou
/storage/emulated/0/Android
/storage/emulated/0/.mn_1021243354
/storage/emulated/0/amap
/storage/emulated/0/backups
/storage/emulated/0/.dlprovider
/storage/emulated/0/.DataStorage
/storage/emulated/0/360
/storage/emulated/0/.sys.log
/storage/emulated/0/DCIM
/storage/emulated/0/miad
/storage/emulated/0/.mn_-980648280
/storage/emulated/0/MiMarket
/storage/emulated/0/data
/storage/emulated/0/mivideo
/storage/emulated/0/Download
/storage/emulated/0/com.miui.voiceassist
/storage/emulated/0/browser
/storage/emulated/0/.Rcs
/storage/emulated/0/.com.android.providers.downloads.ui
/storage/emulated/0/netease
/storage/emulated/0/Tencent
/storage/emulated/0/.UTSystemConfig
/storage/emulated/0/Pictures
/storage/emulated/0/.vivo
/storage/emulated/0/kingdid
/storage/emulated/0/FreeRun
/storage/emulated/0/fac_sources
/storage/emulated/0/wt_logs
/storage/emulated/0/JuphoonService
/storage/emulated/0/dctp
/storage/emulated/0/wlan_logs
/storage/emulated/0/did
/storage/emulated/0/.com.taobao.dp
/storage/emulated/0/baidu
/storage/emulated/0/com.netease.cloudmusic
/storage/emulated/0/.cm_restart_record
/storage/emulated/0/images
/storage/emulated/0/SmartHome
- 獲取頂級共享/外部存儲目錄以及指定類型目錄的文件
public static File getExternalStoragePublicDirectory(String type)
type 類型如下:
常量 | 目錄說明 |
---|---|
Environment.DIRECTORY_MUSIC | 標準的音樂存放目錄 |
Environment.DIRECTORY_PODCASTS | 標準的系統廣播存放目錄 |
Environment.DIRECTORY_RINGTONES | 標準的系統鈴聲存放目錄 |
Environment.DIRECTORY_ALARMS | 標準的系統提醒鈴聲存放目錄 |
Environment.DIRECTORY_NOTIFICATIONS | 標準的系統通知鈴聲存放目錄 |
Environment.DIRECTORY_PICTURES | 標準的相冊存放目錄 |
Environment.DIRECTORY_MOVIES | 標準的電影存放目錄 |
Environment.DIRECTORY_DOWNLOADS | 標準的下載存放目錄 |
Environment.DIRECTORY_DCIM | 標準的相機拍攝照片和視頻存放目錄 |
Environment.DIRECTORY_DOCUMENTS | 標準的文檔存放目錄 |
對應常量值:
public static String DIRECTORY_MUSIC = "Music";
public static String DIRECTORY_PODCASTS = "Podcasts";
public static String DIRECTORY_RINGTONES = "Ringtones";
public static String DIRECTORY_ALARMS = "Alarms";
public static String DIRECTORY_NOTIFICATIONS = "Notifications";
public static String DIRECTORY_PICTURES = "Pictures";
public static String DIRECTORY_MOVIES = "Movies";
public static String DIRECTORY_DOWNLOADS = "Download";
public static String DIRECTORY_DCIM = "DCIM";
public static String DIRECTORY_DOCUMENTS = "Documents";
- 獲取外部存儲設備的當前狀態
public static String getExternalStorageState()
返回值如下:
常量 | 說明 |
---|---|
Environment.MEDIA_UNKNOWN | 未知存儲狀態 |
Environment.MEDIA_REMOVED | 移除狀態:SDCard成功移除 |
Environment.MEDIA_UNMOUNTED | 未掛載:識別到SDCard,但沒有掛載 |
Environment.MEDIA_CHECKING | 檢查狀態:檢查SDCard的有效性 |
Environment.MEDIA_NOFS | NOFS狀態:識別到SDCard卡,但無法掛載。無法掛載原因,可能是SDCard無存儲介質,或者SDCard卡的文件系統與Android無兼容 |
Environment.MEDIA_MOUNTED | 掛載狀態:SDCard卡已經成功掛載 |
Environment.MEDIA_MOUNTED_READ_ONLY | 只讀狀態:SDCard已經掛載,但是是隻讀的 |
Environment.MEDIA_SHARED | 共享狀態:識別到SDCard卡,但SDCard未掛載,而是作爲mass storage等設備(如以u盤的方式連接到電腦上) |
Environment.MEDIA_BAD_REMOVAL | 非法移除狀態:移除SDCard之前,沒有卸載SDCard |
Environment.MEDIA_UNMOUNTABLE | 無法掛載狀態:識別到sdcard卡,但無法掛載。無法掛載的原因,可能是SDCard的存儲介質部分損壞 |
對應常量值:
public static final String MEDIA_UNKNOWN = "unknown";
public static final String MEDIA_REMOVED = "removed";
public static final String MEDIA_UNMOUNTED = "unmounted";
public static final String MEDIA_CHECKING = "checking";
public static final String MEDIA_NOFS = "nofs";
public static final String MEDIA_MOUNTED = "mounted";
public static final String MEDIA_MOUNTED_READ_ONLY = "mounted_ro";
public static final String MEDIA_SHARED = "shared";
public static final String MEDIA_BAD_REMOVAL = "bad_removal";
public static final String MEDIA_UNMOUNTABLE = "unmountable";
- 返回指定路徑共享/外部存儲設備的當前狀態
public static String getExternalStorageState(File path)
返回值與 static String getExternalStorageState() 一致。
- 設備的外存是否是用內存模擬的,是則返回true
public static boolean isExternalStorageEmulated()
- 返回主“外部存儲設備是否是可拆卸的。
public static boolean isExternalStorageRemovable()
2.Context提供的存儲路徑
- 返回設備外部存儲上目錄的絕對路徑,應用程序可以在其中放置其擁有的永久文件。
- 這些文件是應用程序的內部文件,通常不會作爲媒體顯示給用戶。
- 同時當應用被卸載時,這些文件將會被刪除。
- 例:/storage/emulated/0/Android/data/應用包名/files/type
@Nullable
public abstract File getExternalFilesDir(@Nullable String type);
參數type取值說明:
type取值與 getExternalStoragePublicDirectory 一樣,存儲路徑不同。
getExternalFilesDir 存儲的目錄卻是在 /storage/emulated/0/Android/data/應用包名/files/type
示例如下:
val mFile = applicationContext.getExternalFilesDirs(Environment.DIRECTORY_PICTURES)
if (mFile.isNotEmpty()){
mFile.iterator().forEach {
Log.e(javaClass.simpleName, it.path)
}
}
打印輸出:/storage/emulated/0/Android/data/com.files.sample/files/Pictures
- 應用程序如果有obb文件,則返回應用程序的obb文件的外部存儲目錄的絕對路徑。例:/storage/emulated/0/Android/obb/應用報名
public abstract File getObbDir();
示例如下:
val mFile = applicationContext.obbDir
Log.e(javaClass.simpleName, mFile.path)
打印輸出:/storage/emulated/0/Android/obb/com.files.sample
- 應用程序如果有obb文件,則返回應用程序的obb文件的外部存儲目錄的絕對路徑的集合。通過 forEach 便利可查看全部。
public abstract File[] getObbDirs();
示例如下:
val mFile = applicationContext.obbDirs
if (mFile != null && mFile.isNotEmpty()) {
mFile.iterator().forEach {
Log.e(javaClass.simpleName, it.path)
}
}
打印輸出:/storage/emulated/0/Android/obb/com.files.sample