標籤:
Android使用檔案系統來讀取和儲存檔案的, 相關的包請參照java.io包下面的檔案。
1) 選擇內部儲存(Internal Storage)或者是外部儲存(External Storage)
Android裝置有兩個儲存地區:內部儲存和外部儲存空間, 顧名思義, 內部儲存是跟隨android系統的, 外部系統是可拆卸的裝置例如SD card等。
對於很多Android裝置, 即使沒有前面所說的外部裝置(如SD card), 系統同樣提供在內部儲存地區上提供了一塊空間作為"外部儲存"。因此即使
沒有可拆卸的外設,仍然後兩套儲存空間可供選擇。API對兩種外部裝置是同樣適用的。 下面是兩種儲存空間的一些特性:
a. 內部裝置(Internal Storage)
1. 內部裝置是一直存在的,並且是一直有效。
2. 預設情況下,儲存在內部裝置上的檔案只能被自己的app單獨訪問。
3. 當卸載app的時候,系統會移除所有的儲存在內部裝置上的app檔案。
由以上特點可以看出, 內部裝置適合儲存那些只有自己的app訪問的資料和檔案。 比如登入後的使用者資訊, 資料庫檔案等私密資訊。
b. 外部裝置(External Storage)
1. 外部裝置並不保證是一直存在且有效。比如user可能掛載了外部裝置然後移除了它。
2. 外部裝置是"公用地區", 儲存在外部裝置上的檔案無法控制其私密性,其他app可以讀取操作它。
3. 當卸載app的時候,系統只會移除儲存在getExternalFilesDir()檔案夾下的檔案,其他的檔案不會主動移除。 也就是說,會產生垃圾資料。
對比內部裝置, 可以看出外部裝置適合儲存那些不需要閱讀許可權的檔案。
2) 擷取讀寫權限。
為了讀取外部裝置,需要在manifest中添加讀寫權限:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
值得注意的是, 現在所有的app均有能力讀取外部裝置,並不需要特殊的讀許可權。 但是在未來的Android版本中,會加入更多的限制。
因此在你的app中,同樣需要添加讀許可權已防備未來更新版本帶來的麻煩。
<manifest ...>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
...
</manifest>
而讀寫內部裝置不需要任何許可權。 app擁有讀寫它的內部儲存空間的權利。
3) 隱藏檔到內部裝置
當需要隱藏檔到內部空間時,可以通過File類的兩種方法來擷取儲存路徑
getFilesDir() 會返回你的app的內部儲存空間的路徑
getCacheDir() 返回你的app的內部儲存空間的緩衝目錄, 如果快取檔案不太需要的話,請及時清理已保證緩衝目錄的以保證快取檔案不會佔用太大空間,
比如1M, 不然系統有可能在沒有警告的情況下直接刪除緩衝目錄下的檔案。
如果要在背部裝置上建立檔案,可以使用如下代碼:
File file = new File(context.getFilesDir(), filename);
相應的,可以使用openFileOutput() 來擷取FileOutputStream , 然後通過它來寫檔案到內部裝置。下面是例子:
String filename = "myfile"; String string = "Hello world!"; FileOutputStream outputStream; try { outputStream = openFileOutput(filename, Context.MODE_PRIVATE); outputStream.write(string.getBytes()); outputStream.close(); } catch (Exception e) { e.printStackTrace(); }
或者是,你同樣可以使用createTempFile()來建立檔案, 下面的例子是通過url擷取檔案名稱,然後儲存在緩衝目錄下:
public File getTempFile(Context context, String url) { File file; try { String fileName = Uri.parse(url).getLastPathSegment(); file = File.createTempFile(fileName, null, context.getCacheDir()); catch (IOException e) { // Error while creating file } return file; }
內部裝置的目錄是以你的包名儲存的, 從技術上來說, 如果你把檔案儲存成readble模式,其他的app可以讀取此檔案,當然它要知道
你的包名和你的檔案名稱。其他的app不能瀏覽你的內部檔案夾, 如果你沒有把檔案屬性設定為readable或者writable。
只要你使用MODE_PRIVATE模式,其他的app就不能訪問你的檔案。
4) 外部儲存空間
因為外部空間是可拆卸的,因此在訪問它之前,必須確保其存在。 Android提供了響應的介面來判斷外設是否可用。當外設的狀態為MEDIA_MOUNTED,即意味著外設可讀寫。
下面的代碼可以用來檢查外設是否可用
/* Checks if external storage is available for read and write */ public boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } return false; } /* Checks if external storage is available to at least read */ public boolean isExternalStorageReadable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { return true; } return false; }
前面也提到過,外設上的檔案也有區別, 有的隨著app的卸載會被系統同時刪除,有些目下的檔案不會同時被刪除。
因此, 根據你的檔案的類型,你可以選擇將他們儲存在不同的目錄下:
共有檔案:
這些檔案可同時被其他的app使用,當卸載時,不希望被刪除,比如下載的圖片,或者使用app拍攝的照片等。
私人檔案:
你的app的單獨使用的檔案,在卸載時,希望同時被刪除,儘管這些檔案能夠被其他的app訪問,但對使用者已經沒有價值。例如一些快取資料。
當你儲存共有檔案時,可以使用getExternalStoragePublicDirectory()方法來擷取外設的根目錄,在此根目錄上建立新的檔案路徑。
這個方法需要指定你需要儲存的類型,比片或者音樂等。例如:
public File getAlbumStorageDir(String albumName) { // Get the directory for the user's public pictures directory. File file = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), albumName); if (!file.mkdirs()) { Log.e(LOG_TAG, "Directory not created"); } return file; }
當你需要儲存私人檔案時,可以通過getExternalFilesDir(), 同樣可以指定需要的類型, 例子如下:
public File getAlbumStorageDir(Context context, String albumName) { // Get the directory for the app's private pictures directory. File file = new File(context.getExternalFilesDir( Environment.DIRECTORY_PICTURES), albumName); if (!file.mkdirs()) { Log.e(LOG_TAG, "Directory not created"); } return file; }
如果不需要指定類型,可以傳遞null到getExternalFilesDir()中,它返回的是您的應用程式的在外部儲存的根目錄。
記住兩者之間的區別。
5) 查詢剩餘空間
如果你知道需要儲存的檔案的大小,你需要保證有足夠的空間來儲存這些檔案。
可以通過getFreeSpace() 或者 getTotalSpace() 來擷取檔案的大小。
6) 刪除檔案:
可以通過File的delete()方法來刪除檔案。或者通過context.deteleFile(fileName)來刪除內部空間的檔案。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Android檔案儲存體