Android中的文件讀寫操作是不可或缺的,每個應用都會涉及到讀寫操作。這裏將讀寫操作分成了四個部分
assets文件夾中文件數據的讀取
raw文件夾中的文件數據的讀取
Android內部存儲文件的讀寫
Android外部存儲文件的讀寫
一、讀取assets文件夾中的數據
assets文件夾 和 res文件夾 的區別:
Android系統不爲assets文件夾下的文件生成ID。如果使用assets下的文件,需要指定文件的路徑和文件名。存放在assets文件夾中的資源不會生成id,但是存放在res目錄下的資源會生成id。
assets 和 res下的文件都是只能讀不能寫 。
Android中的資源文件主要分爲兩類,一種出於assets目錄下,稱爲原生文件,這類文件在被打包成apk文件時是不會進行壓縮的;另一類則是res下的文件,這類文件在打包成apk文件時,會進行小內存優化 。
雖然通過一個字符串路徑來獲取這個目錄下的文件描述符,訪問的速度會慢。但是把一些文件放在這個目錄下會使一些操作更加方便,比方說拷貝一個數據庫文件到系統內存中。要注意的是,你無法在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卡的目錄查找步驟:
首先在虛擬機根目錄能直接看到sdcard目錄,然後我們查看他的info指向目錄:/storage/emulated/legacy
接下來我們進入/storage/emulated/legacy目錄,但是啥都沒有,但是這個目錄的info指向了另一個目錄:/mnt/shell/emulated/0
我們進入/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
注意:
InputStream 、OutputStream、FileInputStream 、FileOutputStream操作的是字節流
InputStreamReader 、OutputStreamWriter操作的是字符流
英文一個字符佔一個字節,而中文一個字符佔倆字節。如果用stream,讀出來的英語再倒也罷了,但讀出來的中文就會出現亂碼。