1. 程式人生 > 其它 >Android學習路線_入門篇(九)資料持久化之檔案讀寫

Android學習路線_入門篇(九)資料持久化之檔案讀寫

技術標籤:Android學習路線android

資料持久化是保證資料在程式銷燬、裝置關機後仍然不會丟失的操作,Android系統上主要有三種方式。第二個再說說檔案讀寫,在日常開發中很多資料是以檔案的形式進行儲存的,根據檔案的位置存在四種不同的讀寫方式,主要包括raw、assets、InternalStorage、ExternalStorage。

本文已收錄至☞Android學習路線_梳理
上一篇☞Android學習路線_入門篇(八)資料持久化之SharedPreferences

1. raw檔案

raw檔案是在專案中的res/raw資料夾下,res/raw中的檔案會被對映到R.java檔案中,訪問的時候直接使用資源ID即可。

通過getResource.openRawResource()將檔案讀取為位元組流,由於檔案被影射到R.java檔案中,所以引數可以直接使用R.raw.info,而後通過檔案的一般讀取方式進行讀取。

InputStream is = getResources().openRawResource(R.raw.info);
InputStreamReader isr = new InputStreamReader(is);
BufferedReader bfr = new BufferedReader(isr);
String in = "";
try{
	while((in =
bfr.readLine()) != null){ Log.i(TAG, in); } } catch (Exception e) { e.printStackTrace(); } is.close();

2. assets檔案

assets目錄下的檔案在打包後會原封不動的儲存在apk包中,不會被編譯成二進位制,可以有目錄結構,也就是assets目錄下可以再建立資料夾。

通過getResource()或AssetsManager的getAssets().open(檔名)方法獲取位元組流,而後通過檔案的一般讀取方式進行讀取。

InputStream is = getResources
().getAssets().open("info.txt"); InputStreamReader isr =newInputStreamReader(is,"UTF-8"); BufferedReader bfr =newBufferedReader(isr); String in =""; try{ while((in = bfr.readLine()) != null){ Log.i(TAG, in); } } catch (Exception e) { e.printStackTrace(); } is.close();

3. InternalStorage檔案

內部儲存(Internal Storage)總是可用的,檔案預設情況儲存在/data/data/包名/files,快取檔案儲存在/data/data/包名/cache中,預設情況下只能只能被本APP操作,當然可以在openFileOutput()中指定是否可被其他app讀寫。

當使用者解除安裝你的app時,系統會自動從內部儲存中刪除你的app對應資料夾下的所有檔案。

使用OpenFileOutput(filename,寫入模式)方法,可以在應用內部儲存中自動建立files資料夾,在files資料夾中,建立相應檔名的檔案。

3.1 寫入資料

呼叫OpenFileOutput(filename,寫入模式)方法,得到FileOutputStream,包裝成OutputStreamWriter,然後呼叫write方法進行寫入,沖刷緩衝區,關閉流。

try{
	String content = "寫入資料內容";
	FileOutputStream fos = openFileOutput("info.text",Context.MODE_PRIVATE);
	OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
	osw.write(content);
	osw.flush();
	fos.flush();
	osw.close();
	fos.close();
} catch (Exception e) {
	e.printStackTrace();
}

3.2 讀取資料

呼叫OpenFileInput(filename)方法,得到FileInputStream,包裝成InputStreamReader,建立字元陣列,然後呼叫read方法進行讀取,沒有沖刷緩衝區。記得關閉流,可將字元陣列轉換為 String。

try{
	FileInputStream fis = openFileInput("info.text");
	InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
	charinput[] = new char[fis.available()];
	isr.read(input);
	isr.close();
	fis.close();
	String in = new String(input);
	Log.i(TAG, in);
} catch (Exception e) {
	e.printStackTrace();
}

4. ExternalStorage檔案

外部儲存(External storage)並不是總是可用,因為使用者有可能將SD卡作為USB儲存掛載或者在某些情況下將SD卡從裝置上卸下,因此需要使用getExternalStorageState()來查詢外部儲存的狀態,當返回的狀態是MEDIA_MOUNTED時才能讀寫。一些裝置將"internal" 與 “external” 都做成了不可解除安裝的內建儲存,雖然如此,但是這一整塊還是從邏輯上有被劃分為"internal"與”external”。

儲存在外部儲存的檔案是world-readable的,所以儲存在外部儲存的檔案可能被其他應用讀取。

當用戶解除安裝你的app時,系統只會刪除你的app中通過呼叫getExternalFilesDir()來儲存的檔案。

並且在使用外部儲存時還需要在AndroidManifest檔案中申請對應的許可權:

// 向SD卡寫入資料許可權,隱式授予了讀取許可權
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
// 當app只需要讀取而非寫入許可權的時候更適合使用該許可權
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
// 在SD卡中建立和刪除檔案許可權
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

4.1 寫入資料

首先通過Environment.getExternalStorageState()判斷SD卡的狀態,隨後根據寫入位置和檔名稱拿到對應的File物件,並對檔案路徑和檔案進行建立,最後將資料寫入檔案並關閉輸出流。

String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)){
	Toast.makeText(getApplicationContext(),"sd卡不可寫入",Toast.LENGTH_SHORT).show();
	return;
}
String fileName = "info.text";
String content = "寫入資料內容";
File myFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), fileName);
if (!myFile.mkdirs()){
    Log.d(TAG,"Directory not create");
}
if(!myFile.exists()){
	try{
		myFile.createNewFile();
	}catch(IOException e) {
		Toast.makeText(getApplicationContext(),"檔案建立失敗",Toast.LENGTH_SHORT).show();
		e.printStackTrace();
	}
}
try{
	FileOutputStream fos =newFileOutputStream(myFile);
	OutputStreamWriter osw =newOutputStreamWriter(fos);
	osw.write(content);
	osw.flush();
	fos.flush();
	osw.close();
	fos.close();
}catch(Exception e) {
	e.printStackTrace();
}

4.2 讀取資料

首先通過Environment.getExternalStorageState()判斷SD卡的狀態,隨後根據讀取位置和檔名稱拿到對應的File物件,並對檔案路徑和檔案進行建立,最後將檔案中的資料進行讀取並關閉輸入流。

String state=Environment.getExternalStorageState();
if (!(Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state))){
	Toast.makeText(getApplicationContext(),"sd卡不可讀取",Toast.LENGTH_SHORT).show();
	return;
}
String fileName = "info.text";
File myFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), fileName);
if (!myFile.mkdirs()){
    Log.d(TAG,"Directory not create");
}
if(!myFile.exists()) {
	try{
		myFile.createNewFile();
	}catch(IOException e) {
		e.printStackTrace();
	}
}
try{
	FileInputStream fis =newFileInputStream(myFile);
	InputStreamReader isr =newInputStreamReader(fis);
	BufferedReader br =newBufferedReader(isr);
	StringBuilder strBuilder =newStringBuilder();
	String line ="";
	while((line = br.readLine()) !=null) {
		strBuilder.append(line);
	}
	br.close();
	isr.close();
	fis.close();
	Log.i(TAG, strBuilder.toString());
}catch(Exception e) {
	e.printStackTrace();
}

完畢

今天的分享就到這裡,文章多有不足,各位小夥伴有什麼想法可以直接評論或是私信,要是對你有所幫助就給我一個贊吧,喜歡我的小夥伴可以關注我哦~

本文已收錄至☞Android學習路線_梳理
上一篇☞Android學習路線_入門篇(八)資料持久化之SharedPreferences

支援我的小夥伴們可以微信搜尋“Android思維庫”,或者微信掃描下方二維碼,關注我的公眾號,每天都會推送新知識~