編輯:關於Android編程
本文講述如何使用 Android 文件系統通過 File API 讀取和寫入文件。
File 對象適合按照從開始到結束的順序不跳過地讀取或寫入大量數據。 例如,它適合於圖片文件或通過網絡交換的任何內容。
假定您熟悉 Linux 文件系統的基礎知識和 java.io 中的標准文件輸入/輸出 API。
所有 Android 設備都有兩個文件存儲區域:“內部”和“外部”存儲。這些名稱在 Android 早期產生,當時大多數設備都提供內置的非易失性內存(內部存儲),以及移動存儲介質,比如微型 SD 卡(外部存儲)。一些設備將永久性存儲空間劃分為“內部”和“外部”分區,即便沒有移動存儲介質,也始終有兩個存儲空間,並且無論外部存儲設備是否可移動,API 的行為均一致。以下列表匯總了關於各個存儲空間的實際信息。
它始終可用。
只有您的應用可以訪問此處保存的文件。
當用戶卸載您的應用時,系統會從內部存儲中移除您的應用的所有文件。
當您希望確保用戶或其他應用均無法訪問您的文件時,內部存儲是最佳選擇。
它並非始終可用,因為用戶可采用 USB 存儲設備的形式裝載外部存儲,並在某些情況下會從設備中將其移除。
它是全局可讀的,因此此處保存的文件可能不受您控制地被讀取。
當用戶卸載您的應用時,只有在您通過 getExternalFilesDir() 將您的應用的文件保存在目錄中時,系統才會從此處移除您的應用的文件。
對於無需訪問限制以及您希望與其他應用共享或允許用戶使用計算機訪問的文件,外部存儲是最佳位置。
在 Android N 之前,內部文件可以通過放寬文件系統權限讓其他應用訪問。而如今不再是這種情況。如果您希望讓其他應用訪問私有文件的內容,則您的應用可使用 FileProvider。
盡管應用默認安裝在內部存儲中,但您可在您的清單文件中指定 android:installLocation 屬性,這樣您的應用便可安裝在在外部存儲中。當 APK 非常大且它們的外部存儲空間大於內部存儲時,用戶更青睐這個選擇。 如需了解詳細信息,請參閱應用安裝位置。
要向外部存儲寫入信息,您必須在您的清單文件中請求 WRITE_EXTERNAL_STORAGE 權限。
目前,所有應用都可以讀取外部存儲,而無需特別的權限。 但這在將來版本中會進行更改。如果您的應用需要讀取外部存儲(但不向其寫入信息),那麼您將需要聲明 READ_EXTERNAL_STORAGE 權限。要確保您的應用繼續正常工作,您應在更改生效前聲明此權限。
在內部存儲中保存文件時,您可以通過調用以下兩種方法之一獲取作為 File 的相應目錄:
1.getFilesDir()
返回表示您的應用的內部目錄的 File 。
2.getCacheDir()
返回表示您的應用臨時緩存文件的內部目錄的 File。 務必刪除所有不再需要的文件並對在指定時間您使用的內存量實現合理大小限制,比如,1MB。 如果在系統即將耗盡存儲,它會在不進行警告的情況下刪除您的緩存文件。
1.您可以使用 File() 構造函數,傳遞指定您的內部存儲目錄的上述方法之一所提供的 File。例如:
File file = new File(context.getFilesDir(), filename);
2.或者,您可以調用 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(); }
3.或者,如果您需要緩存某些文件,您應改用 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; }
注:您的應用的內部存儲設備目錄由您的應用在 Android 文件系統特定位置中的軟件包名稱指定。從技術上講,如果您將文件模式設置為可讀,那麼,另一應用也可以讀取您的內部文件。 但是,此應用也需要知道您的應用的軟件包名稱和文件名。 其他應用無法浏覽您的內部目錄並且沒有讀寫權限,除非您明確將文件設置為可讀或可寫。 只要您為內部存儲上的文件使用 MODE_PRIVATE,其他應用便從不會訪問它們。
由於外部存儲可能不可用—比如,當用戶已將存儲裝載到電腦或已移除提供外部存儲的 SD 卡時—因此,在訪問它之前,您應始終確認其容量。 您可以通過調用 getExternalStorageState() 查詢外部存儲狀態。 如果返回的狀態為 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; }
應供其他應用和用戶自由使用的文件。 當用戶卸載您的應用時,用戶應仍可以使用這些文件。
例如,您的應用拍攝的照片或其他已下載的文件。
屬於您的應用且在用戶卸載您的應用時應予刪除的文件。 盡管這些文件在技術上可被用戶和其他應用訪問(因為它們存儲在外部存儲中), 但它們實際上不向您的應用之外的用戶提供任何輸出值。 當用戶卸載您的應用時,系統會刪除應用外部私有目錄中的所有文件。
例如,您的應用下載的其他資源或臨時介質文件。
如果您要將公共文件保存在外部存儲設備上,請使用 getExternalStoragePublicDirectory() 方法獲取表示外部存儲設備上相應目錄的 File。 該方法使用指定您想要保存以便它們可以與其他公共文件在邏輯上組織在一起的文件類型的參數,比如 DIRECTORY_MUSIC 或 DIRECTORY_PICTURES。例如:
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;
}
切記,getExternalFilesDir() 在用戶卸載您的應用時刪除的目錄內創建目錄。如果您正保存的文件應在用戶卸載您的應用後仍然可用—比如,當您的應用是照相機並且用戶要保留照片時—您應改用 getExternalStoragePublicDirectory()。
無論您對於共享的文件使用 {@linkandroid.os.Environment#getExternalStoragePublicDirectory getExternalStoragePublicDirectory()} 還是對您的應用專用文件使用 getExternalFilesDir(),您使用諸如 DIRECTORY_PICTURES 的 API 常數提供的目錄名稱非常重要。這些目錄名稱可確保系統正確處理文件。 例如,保存在 DIRECTORY_RINGTONES 中的文件由系統媒體掃描程序歸類為鈴聲,而不是音樂。
如果您事先知道您將保存的數據量,您可以查出是否有足夠的可用空間,而無需調用 getFreeSpace() 或 getTotalSpace() 引起 IOException。這些方法分別提供目前的可用空間和存儲卷中的總空間。 此信息也可用來避免填充存儲卷以致超出特定阈值。
但是,系統並不保證您可以寫入與 getFreeSpace() 指示的一樣多的字節。如果返回的數字比您要保存的數據大小大出幾 MB,或如果文件系統所占空間不到 90%,則可安全繼續操作。否則,您可能不應寫入存儲。
注:保存您的文件之前,您無需檢查可用空間量。 您可以嘗試立刻寫入文件,然後在 IOException 出現時將其捕獲。 如果您不知道所需的確切空間量,您可能需要這樣做。 例如,如果在保存文件之前通過將 PNG 圖像轉換成 JPEG 更改了文件的編碼,您事先將不知道文件的大小。
您應始終刪除不再需要的文件。刪除文件最直接的方法是讓打開的文件參考自行調用 delete()。
myFile.delete();
如果文件保存在內部存儲中,您還可以請求 Context 通過調用 deleteFile() 來定位和刪除文件:
myContext.deleteFile(fileName);
您保存在內部存儲中的所有文件
您使用 getExternalFilesDir() 保存在外部存儲中的所有文件。
但是,您應手動刪除使用 getCacheDir() 定期創建的所有緩存文件並且定期刪除不再需要的其他文件。
在Android的源代碼中,經常會看到形如:sp<xxx>、wp<xxx>這樣的類型定義,這其實是Android中的智能 指針。智能
本節引言: Android入門系列已經寫了大半了,學習了這麼多理論知識,不練下手怎麼行呢? 在實際的開發中我們會遇到更多的問題,
榮耀6plus有著紅外遙控功能,相信入手榮耀6plus的同學都很想試試自己的手機當遙控是什麼感覺吧。華為榮耀6plus不僅僅是手機,不僅可以做智能手機,下載
Android 長按返回健退出背景平常比較常見的都是一定時間間隔內按兩次返回鍵來退出應用,並且第一次點擊會有相應的提示,網上資料比較多,這裡寫一下,長按返回鍵