【轉】Android必備知識點- Android檔案(File)操作

來源:互聯網
上載者:User

標籤:歸類   read_only   mod   電腦   isp   equal   建立   使用   外部   

Android 使用與其他平台上基於磁碟的檔案系統類似的檔案系統。

本文講述如何使用 Android 檔案系統通過 File API 讀取和寫入檔案。

File 對象適合按照從開始到結束的順序不跳過地讀取或寫入大量資料。 例如,它適合於圖片檔案或通過網路交換的任何內容。

本文展示如何在您的應用中執行基本的檔案相關任務。

假定您熟悉 Linux 檔案系統的基礎知識和 java.io 中的標準檔案輸入/輸出 API。

選擇內部或外部儲存

所有 Android 裝置都有兩個檔案儲存體地區:“內部”和“外部”儲存。這些名稱在 Android 早期產生,當時大多數裝置都提供內建的非易失性記憶體(內部儲存),以及移動儲存介質,比如微型 SD 記憶卡(外部儲存)。一些裝置將非揮發性儲存體空間劃分為“內部”和“外部”分區,即便沒有移動儲存介質,也始終有兩個儲存空間,並且無論外部存放裝置是否可移動,API 的行為均一致。以下列表匯總了關於各個儲存空間的實際資訊。

內部儲存:

它始終可用。
只有您的應用可以訪問此處儲存的檔案。
當使用者卸載您的應用時,系統會從內部儲存中移除您的應用的所有檔案。
當您希望確保使用者或其他應用均無法訪問您的檔案時,內部儲存是最佳選擇。

外部儲存:

它並非始終可用,因為使用者可採用 USB 存放裝置的形式裝載外部儲存,並在某些情況下會從裝置中將其移除。
它是全域可讀的,因此此處儲存的檔案可能不受您控制地被讀取。
當使用者卸載您的應用時,只有在您通過 getExternalFilesDir() 將您的應用的檔案儲存在目錄中時,系統才會從此處移除您的應用的檔案。
對於無需訪問限制以及您希望與其他應用共用或允許使用者使用電腦訪問的檔案,外部儲存是最佳位置。

註:

在 Android N 之前,內部檔案可以通過放寬檔案系統許可權讓其他應用訪問。而如今不再是這種情況。如果您希望讓其他應用訪問私人檔案的內容,則您的應用可使用 FileProvider。

提示:

儘管應用預設安裝在內部儲存中,但您可在您的資訊清單檔中指定 android:installLocation 屬性,這樣您的應用便可安裝在在外部儲存中。當 APK 非常大且它們的外部儲存空間大於內部儲存時,使用者更青睞這個選擇。 如需瞭解詳細資料,請參閱應用安裝位置。

擷取外部儲存的許可權

要向外部儲存寫入資訊,您必須在您的資訊清單檔中請求 WRITE_EXTERNAL_STORAGE 許可權。

<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>

注意:

目前,所有應用都可以讀取外部儲存,而無需特別的許可權。 但這在將來版本中會變更。如果您的應用需要讀取外部儲存(但不向其寫入資訊),那麼您將需要聲明 READ_EXTERNAL_STORAGE 許可權。要確保您的應用繼續正常工作,您應在更改生效前聲明此許可權。

<manifest ...>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
...
</manifest>

但是,如果您的應用使用 WRITE_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() 並傳遞 null。這將返回外部儲存上您的應用的專用目錄的根目錄。

切記,getExternalFilesDir() 在使用者卸載您的應用時刪除的目錄內建立目錄。如果您正儲存的檔案應在使用者卸載您的應用後仍然可用—比如,當您的應用是照相機並且使用者要保留照片時—您應改用 getExternalStoragePublicDirectory()。

無論您對於共用的檔案使用 {@linkandroid.os.Environment#getExternalStoragePublicDirectory getExternalStoragePublicDirectory()} 還是對您的應用專用檔案使用 getExternalFilesDir(),您使用諸如 DIRECTORY_PICTURES 的 API 常數提供的目錄名稱非常重要。這些目錄名稱可確保系統正確處理檔案。 例如,儲存在 DIRECTORY_RINGTONES 中的檔案由系統媒體掃描程式歸類為鈴聲,而不是音樂。

查詢可用空間

如果您事Crowdsourced Security Testing道您將儲存的資料量,您可以查出是否有足夠的可用空間,而無需調用 getFreeSpace() 或 getTotalSpace() 引起 IOException。這些方法分別提供目前的可用空間和儲存卷中的總空間。 此資訊也可用來避免填充儲存卷以致超出特定閾值。

但是,系統並不保證您可以寫入與 getFreeSpace() 指示的一樣多的位元組。如果返回的數字比您要儲存的資料大小大出幾 MB,或如果檔案系統所佔空間不到 90%,則可安全繼續操作。否則,您可能不應寫入儲存。

註:儲存您的檔案之前,您無需檢查可用空間量。 您可以嘗試立刻寫入檔案,然後在 IOException 出現時將其捕獲。 如果您不知道所需的確切空間量,您可能需要這樣做。 例如,如果在儲存檔案之前通過將 PNG 映像轉換成 JPEG 更改了檔案的編碼,您事先將不知道檔案的大小。

刪除檔案

您應始終刪除不再需要的檔案。刪除檔案最直接的方法是讓開啟的檔案參考自行調用 delete()。

myFile.delete();
如果檔案儲存在內部儲存中,您還可以請求 Context 通過調用 deleteFile() 來定位和刪除檔案:

myContext.deleteFile(fileName);

註:當使用者卸載您的應用時,Android 系統會刪除以下各項:

您儲存在內部儲存中的所有檔案
您使用 getExternalFilesDir() 儲存在外部儲存中的所有檔案。
但是,您應手動刪除使用 getCacheDir() 定期建立的所有快取檔案並且定期刪除不再需要的其他檔案。

【轉】Android必備知識點- Android檔案(File)操作

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.