Android文件讀寫操作(assets 文件、 raw文件、內部存儲文件、外部存儲文件)

Android中的文件讀寫操作是不可或缺的,每個應用都會涉及到讀寫操作。這裏將讀寫操作分成了四個部分

  1. assets文件夾中文件數據的讀取

  2. raw文件夾中的文件數據的讀取

  3. Android內部存儲文件的讀寫

  4. Android外部存儲文件的讀寫


一、讀取assets文件夾中的數據

assets文件夾 和 res文件夾 的區別:

  1. Android系統不爲assets文件夾下的文件生成ID。如果使用assets下的文件,需要指定文件的路徑和文件名。存放在assets文件夾中的資源不會生成id,但是存放在res目錄下的資源會生成id。

  2. assets 和 res下的文件都是只能讀不能寫 。

  3. Android中的資源文件主要分爲兩類,一種出於assets目錄下,稱爲原生文件,這類文件在被打包成apk文件時是不會進行壓縮的;另一類則是res下的文件,這類文件在打包成apk文件時,會進行小內存優化 。

  4. 雖然通過一個字符串路徑來獲取這個目錄下的文件描述符,訪問的速度會慢。但是把一些文件放在這個目錄下會使一些操作更加方便,比方說拷貝一個數據庫文件到系統內存中。要注意的是,你無法在Android XML文件中引用到assets目錄下的文件,只能通過AssetManager來訪問這些文件。數據庫文件和遊戲數據等放在這個目錄下是比較合適的。


  • 當我們使用Android studio創建Android工程項目的時候,assets文件夾不會自動創建,需要我們手動創建。這時我們必須在main目錄下創建assets文件夾。

    如圖:

    這裏寫圖片描述

  • 當我們使用Eclipse創建Android工程項目的時候,assets文件夾會自動創建。如果沒有創建,我們也可以手動創建,目錄如圖:

    這裏寫圖片描述


文件夾創建好以後,我們往文件夾中存放文件,然後就可以通過代碼獲取到assets文件夾中的數據了

 try {
      InputStream is = getResources().getAssets().open("test.txt");
      InputStreamReader isr = new InputStreamReader(is,"UTF-8");
      BufferedReader br = new BufferedReader(isr);
      String str = "";
      while((str = br.readLine()) != null){
           tv.append(str+"\n");  //把test文檔中的內容顯示在tv中
      }
  } catch (IOException e) {
          e.printStackTrace();
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

二、讀取raw文件夾中的數據

raw文件夾是屬於res目錄下的,其中的資源會自動生成id,因此我們引用id就可以使用了。如果res目錄下沒有raw文件夾,我們可以自行在res目錄下創建。這裏不用區分編輯器目錄的差別。目錄結構如下:

這裏寫圖片描述

獲取資源代碼如下:

 try {
     InputStream is = getResources().openRawResource(R.raw.test);
     InputStreamReader isr = new InputStreamReader(is,"UTF-8");
     BufferedReader br = new BufferedReader(isr);
     String str = "";
     while((str = br.readLine()) != null){
          tv.append(str+"\n");
     }
  } catch (IOException e) {
          e.printStackTrace();
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

由於raw是Resources (res)的子目錄,Android會自動的爲這目錄中的所有資源文件生成一個ID,這個ID會被存儲在R類當中,作爲一個文件的引用。這意味着這個資源文件可以很容易的被Android的類和方法訪問到,甚至在Android XML文件中你也可以@raw/的形式引用到它。在Android中,使用ID是訪問一個文件最快捷的方式。MP3和Ogg文件放在這個目錄下是比較合適的。


三、內部存儲文件的讀寫

Android內部存儲文件指的是:應用程序安裝後,都會在Android手機系統的data/data/目錄下新建一個以應用包名爲名的文件夾,在這個文件夾中會包含該應用程序的文件資源,我們稱之爲內部存儲文件,用於區分SD卡 
例如我們使用的例子,其目錄爲:data/data/redowu.file/

這裏寫圖片描述


讀寫內部存儲的文件的操作過程如下:

寫入:

private String filename = "test.txt";
try {
     FileOutputStream fos = openFileOutput(filename, Context.MODE_PRIVATE);
     OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
     osw.write(et.getText().toString());

     osw.flush();
     fos.flush();  //flush是爲了輸出緩衝區中所有的內容

     osw.close();
     fos.close();  //寫入完成後,將兩個輸出關閉

 } catch (FileNotFoundException e) {
     e.printStackTrace();
 } catch (UnsupportedEncodingException e) {
     e.printStackTrace();
 } catch (IOException e) {
     e.printStackTrace();
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

讀取:

try {
    FileInputStream fis = openFileInput(filename);
    InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
    char[] input = new char[fis.available()];  //available()用於獲取filename內容的長度
    isr.read(input);  //讀取並存儲到input中

    isr.close();
    fis.close();//讀取完成後關閉

    String str = new String(input); //將讀取並存放在input中的數據轉換成String輸出
    tv.setText(str);
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

這裏寫圖片描述


四、外部存儲文件的讀寫

外部存儲指的是SD卡。在讀寫SD卡中的文件數據前,我們要先在AndroidManifest中聲明使用SD卡的權限

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

SD卡文件的寫入

File sdcard = Environment.getExternalStorageDirectory();//獲取sd卡路徑
File myfile = new File(sdcard,"file.txt");  //實例化一個File
if (sdcard.exists()){  //判斷是否有sd卡
    try {
        myfile.createNewFile();   //創建myfile.txt
        FileOutputStream fos = new FileOutputStream(myfile);
        OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
        osw.write(et.getText().toString());

        osw.flush();
        fos.flush();
        osw.close();
        fos.close();
    } catch (IOException e) {
         e.printStackTrace();
    }
}else {
    System.out.println("沒有sd卡");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

file.txt是創建在sd卡的根目錄的,我們可以在ddms中查看,這裏我們需要查找sdcard的目錄。我使用的虛擬機sd卡的目錄查找步驟:

  1. 首先在虛擬機根目錄能直接看到sdcard目錄,然後我們查看他的info指向目錄:/storage/emulated/legacy

  2. 接下來我們進入/storage/emulated/legacy目錄,但是啥都沒有,但是這個目錄的info指向了另一個目錄:/mnt/shell/emulated/0

  3. 我們進入/mnt/shell/emulated/0,此時我們纔算找到了sdcard的真實目錄,file.txt就創建在這個目錄下

這裏寫圖片描述


SD卡文件數據的讀取

File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard,"file.txt");
try {
     FileInputStream fis = new FileInputStream(file);
     InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
     char[] input  = new char[fis.available()]; 
     isr.read(input);
     isr.close();
     fis.close();

     String str = new String(input);
     tv.setText(str);
 } catch (FileNotFoundException e) {
     e.printStackTrace();
 } catch (IOException e) {
     e.printStackTrace();
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

注意:

  1. InputStream 、OutputStream、FileInputStream 、FileOutputStream操作的是字節流

  2. InputStreamReader 、OutputStreamWriter操作的是字符流

  3. 英文一個字符佔一個字節,而中文一個字符佔倆字節。如果用stream,讀出來的英語再倒也罷了,但讀出來的中文就會出現亂碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章