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思維庫”,或者微信掃描下方二維碼,關注我的公眾號,每天都會推送新知識~