Android存儲(chǔ)相關(guān)

參考谷歌官方文檔 關(guān)于數(shù)據(jù)保存的說明進(jìn)行摘要概述 原文地址參考鏈接地址:

谷歌官方數(shù)據(jù)保存說明?主要分為三種方式:

一、鍵值對(duì)SharedPreferences

鍵值對(duì)的緩存方式比較適合相對(duì)較小的鍵值集合,有兩種創(chuàng)建或訪問共享文件的方法:getSharedPreferences() 與getPreferences()

這里不對(duì)具體的使用方式做說明,主要關(guān)注不同點(diǎn)

getSharedPreference() 可以在整個(gè)應(yīng)用內(nèi)使用任意的Contex調(diào)用 適用于應(yīng)用內(nèi)部有多處需要讀寫同一個(gè)緩存文件 比如:SharedPreferencessharedPref=context.getSharedPreferences(getString(R.string.preference_file_key),Context.MODE_PRIVATE);

getPreferences() 只屬于單獨(dú)的某個(gè)activity,該方法會(huì)檢索屬于該activity的默認(rèn)共享文件,不用提供名稱 比如:SharedPreferencessharedPref=this.getPreferences(Context.MODE_PRIVATE);

注意:如果創(chuàng)建帶MODE_WORLD_READABLEMODE_WORLD_WRITEABLE的共享首選項(xiàng)文件,那么知道文件標(biāo)識(shí)符 的任何其他應(yīng)用都可訪這些緩存數(shù)據(jù)。實(shí)際開發(fā)中使用最頻繁的還是context.getSharedPreferences("file name",Context.MODE)


二、文件保存(IO操作)

File對(duì)象適合按照從開始到結(jié)束的順序不跳過地讀取或?qū)懭氪罅繑?shù)據(jù)。 例如,它適合于圖像文件或通過網(wǎng)絡(luò)交換的任何內(nèi)容。

先看看谷歌對(duì)內(nèi)部存儲(chǔ)與外部存儲(chǔ)的說明:

所有 Android 設(shè)備都有兩個(gè)文件存儲(chǔ)區(qū)域:“內(nèi)部”和“外部”存儲(chǔ)。這些名稱在 Android 早期產(chǎn)生,當(dāng)時(shí)大多數(shù)設(shè)備都提供內(nèi)置的非易失性內(nèi)存(內(nèi)部存儲(chǔ)),以及移動(dòng)存儲(chǔ)介質(zhì),比如微型 SD 卡(外部存儲(chǔ))。一些設(shè)備將永久性存儲(chǔ)空間劃分為“內(nèi)部”和“外部”分區(qū),即便沒有移動(dòng)存儲(chǔ)介質(zhì),也始終有兩個(gè)存儲(chǔ)空間,并且無論外部存儲(chǔ)設(shè)備是否可移動(dòng),API 的行為均一致。以下列表匯總了關(guān)于各個(gè)存儲(chǔ)空間的實(shí)際信息。

內(nèi)部存儲(chǔ):

它始終可用。

默認(rèn)情況下只有您的應(yīng)用可以訪問此處保存的文件。

當(dāng)用戶卸載您的應(yīng)用時(shí),系統(tǒng)會(huì)從內(nèi)部存儲(chǔ)中刪除您的應(yīng)用的所有文件。

當(dāng)您希望確保用戶或其他應(yīng)用均無法訪問您的文件時(shí),內(nèi)部存儲(chǔ)是最佳選擇。

外部存儲(chǔ):

它并非始終可用,因?yàn)橛脩艨刹捎?USB 存儲(chǔ)的形式裝載外部存儲(chǔ),并在某些情況下會(huì)從設(shè)備中將其刪除。

它是全局可讀的,因此此處保存的文件可能不受您控制地被讀取。

當(dāng)用戶卸載您的應(yīng)用時(shí),只有在您通過getExternalFilesDir()將您的應(yīng)用的文件保存在目錄中時(shí),系統(tǒng)才會(huì)從此處刪除您的應(yīng)用的文件。

對(duì)于無需訪問限制以及您希望與其他應(yīng)用共享或允許用戶使用電腦訪問的文件,外部存儲(chǔ)是最佳位置。

如果只有讀取外部存儲(chǔ)操作只需要加入權(quán)限<use-permission android:name="android.permission.READ_EXTERNAL_STORAGE/>

如果需要讀操作和寫操作 只需要加入些權(quán)限即可<user-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

1. 將文件保存在內(nèi)部存儲(chǔ)?

以下兩種方法可以獲取到當(dāng)前應(yīng)用File內(nèi)部存儲(chǔ)目錄:

getFilesDir() ?返回當(dāng)前應(yīng)用內(nèi)部目錄的File

getCacheDir()?返回當(dāng)前應(yīng)用臨時(shí)緩存目錄的File

因?yàn)樵摲椒ㄊ褂玫氖鞘謾C(jī)內(nèi)存空間,使用該方法我們要注意:必須合理控制改緩存目錄文件大小,比如1MB,android系統(tǒng)會(huì)在內(nèi)存不足時(shí),直接將文件刪掉!

在內(nèi)部存儲(chǔ)中創(chuàng)建文件:

File file = new File(context.getFilesDir(),filename);

或者調(diào)用openFileOutput()寫入文件流:

String filename = "myfile";
String strinig = "hello world!";
FileOutputSream outputStream;
try{
? ? ?outputStream = openFileOutput(filaname,Context.MODE_PRIVATE);
? ? ?outputStream = write(string.getBytes());
? ? ?outputStream.close();
} catch (Exception e) {
? ? ?e.printStackTrace();
}

或者使用createTempFile() 從URL中提取文件 緩存到內(nèi)部存儲(chǔ)中:

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;
}
注意:您的應(yīng)用的內(nèi)部存儲(chǔ)設(shè)備目錄由您的應(yīng)用在Android 文件系統(tǒng)特定位置中的軟件包名稱指定。在技術(shù)上,如果您將文件模式設(shè)置為可讀,另一個(gè)應(yīng)用可以讀取您的內(nèi)部文件。 但是,另一個(gè)應(yīng)用也需要知道您的應(yīng)用的軟件包名稱和文件名。 其他應(yīng)用無法瀏覽您的內(nèi)部目錄并且沒有讀寫權(quán)限,除非您明確將文件設(shè)置為可讀或可寫。 只要您為內(nèi)部存儲(chǔ)上的文件使用MODE_PRIVATE, 其他應(yīng)用便從不會(huì)訪問它們

2.將文件保存在外部存儲(chǔ)

訪問外部存儲(chǔ)之前必須先檢查一下讀寫性:

/*Checks if external storage is available for read and write*/
public boolean isExternalStoreageWritable() {
? ? ? String state = Environment.getExternalStorageState();
? ? ? if (Envirionment.MEDIA_MOUNTED.equals(state)){
? ? ? ? ? return true;
? ? ? }
? ? ? return false;
}
/*Checks if external strorage is available to at least read*/
publi boolean isExternalStorageReadable() {
? ? ? String state = Environment.getExternalStorageState();
? ? ? if (Environment.MEDIA_MOUNTED.equals(state){
? ? ? ? ? ?Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
? ? ? ? ? ?return true;
? ? ? }
? ? ? return false;
}

盡管外部存儲(chǔ)可被用戶和其他應(yīng)用進(jìn)行修改,但您可在此處保存兩類文件:

公共文件

應(yīng)供其他應(yīng)用和用戶自由使用的文件。 當(dāng)用戶卸載您的應(yīng)用時(shí),用戶應(yīng)仍可以使用這些文件。

例如,您的應(yīng)用拍攝的照片或其他已下載的文件。

私有文件

本屬于您的應(yīng)用且應(yīng)在用戶卸載您的應(yīng)用時(shí)刪除的文件。盡管這些文件在技術(shù)上可被用戶和其他應(yīng)用訪問(因?yàn)樗鼈冊(cè)谕獠看鎯?chǔ)上),它們是實(shí)際上不向您的應(yīng)用之外的用戶提供值的文件。當(dāng)用戶卸載您的應(yīng)用時(shí),系統(tǒng)會(huì)刪除應(yīng)用外部專用目錄中的所有文件。

例如,您的應(yīng)用下載的其他資源或臨時(shí)介質(zhì)文件。

讀寫外部存儲(chǔ)上的公共文件使用 getExternalStoragePublicDirectory(),支持系統(tǒng)文件類別比如
DIRECTORY_MUSIC或DIRECTORY_PICTURES:

public File getAlbumStorageDir (String albumName) {
? ? ?//Get the directory for the user's public pircture directory
? ? ?File file = new File(Environment.getExternalStoragePublicDirectory(
? ? ? ? ? ? ? ? ?Environment.DIRECTORY_PICTURES),albumName);
? ? ?if (!file.mkdirs()) {
? ? ? ? ? Log.e(LOG_TAG,"Directory not created");
? ? ?}
? ? ?return file;
}

如果保存我們的應(yīng)用專用文件,調(diào)用getExternalFilesDir()獲取文件目錄 并傳遞目錄類型參數(shù),通過這個(gè)方法創(chuàng)建的目錄會(huì)被封裝到我們的應(yīng)用所有外部存儲(chǔ)文件的父目錄下,當(dāng)應(yīng)用被卸載時(shí),這個(gè)父目錄下的文件都會(huì)被刪除。例如,可以使用如下方法創(chuàng)建個(gè)人相冊(cè):

public File getAlbumStorageDir(Context context,String albumName) {
? ? //Get the directory for the app's private pictures directory.
? ? File file ?= new File(context.getExternalFilesDir(
? ? ? ? ? ?Environment.DIRECORY_PICTURES),albumName);
? ? if (!file.mkdirs()) {
? ? ? ? ?Log.e(LOG_TAG,"Directory not created");
? ? }
? ? return file;
}

如果沒有定義子目錄的名稱,可以調(diào)用getExternalFilesDir()并傳遞null,返回的是外部存儲(chǔ)上我們應(yīng)用的專用目錄的根目錄。切記,getExternalFilesDir()創(chuàng)建的目錄在應(yīng)用卸載時(shí)會(huì)被刪除

不管是用getExternalStoragePublicDirectory()操作共享文件還是用getExternalFilesDir()操作應(yīng)用專用文件,使用DIRRECTORY_PICTURES 常數(shù)參數(shù)對(duì)應(yīng)的目錄非常重要,這些目錄可以確保系統(tǒng)正確處理文件。例如,保存在DIRECTORY_RINGTONES中的文件有系統(tǒng)介質(zhì)掃描程序歸類為鈴聲,而不是音樂。


3.查詢可用空間

如果知道將要保存的數(shù)據(jù)量,可以查出是否有足夠的可用空間,不用調(diào)用getFreeSpace()或 getTotalSpace()引起IOException。它們表示目前可用空間 和存儲(chǔ)卷中的總空間。此信息可以用來避免填充在存儲(chǔ)卷的容量超出特定閾值。
但是系統(tǒng)并不保證我們可以寫入 與getFreeSpace()得的一樣多的字節(jié),如果返回的數(shù)組比我們要保存的數(shù)據(jù)大小大出幾MB,或者文件系統(tǒng)所占空間不到90%,則可以安全繼續(xù)操作,否則,可能會(huì)寫入存儲(chǔ)失敗。

注意:保存文件之前,不用檢查空間可用量??梢試L試立刻寫入文件,然后在IOException出現(xiàn)時(shí)將其捕獲。例如,如果在保存文件之前見PNG圖片轉(zhuǎn)換成JPEG更改了文件編碼,這種情況下是無預(yù)知文件大小的.

4.刪除文件


刪除文件最直接的方法,就是讓打開的文件自行調(diào)用delete():

myFile.delete();

如果文件保存在內(nèi)部存儲(chǔ)中,可以使用Context調(diào)用deleteFile()定位和刪除文件:

myContext.deleteFile(fileName);

注意:當(dāng)應(yīng)用被卸載時(shí),Android系統(tǒng)會(huì)刪除一下各項(xiàng):
保存在內(nèi)部存儲(chǔ)中的所有文件
使用getExternalFilesDir()保存在外部存儲(chǔ)中的所有文件。
但是,必須手動(dòng)刪除使用getCacheDir()定期創(chuàng)建的所有緩存文件并且定期刪除不再需要的其他文件

三、使用SQL數(shù)據(jù)庫(kù)保存數(shù)據(jù)

將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)對(duì)于重復(fù)或結(jié)構(gòu)化數(shù)據(jù)(比如契約信息) 而言是理想之選,這里不作具體描述,因?yàn)閍ndroid sql的使用根據(jù)應(yīng)用場(chǎng)景的多邊性 沒有固定模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容