Android開發筆記之文件訪問
之前我們學習了通過preference和SQLite數據庫進行數據存儲,也可以通過文件方式。文件可以是在應用打包時預置,也可以是應用所生成。
文件訪問有兩種方式:一:靜態數據的文件可以防止在res/raw中,這些文件是隻讀的,只有在應用版本升級的時候進行修改,或者我們先讀出這些數據,通過 reference的方式來處理,這樣以後可以進行修訂,但是這種方式,會有兩份數據保存。二:另一種方式是通過URL訪問文件,動態數據的讀取也可以採用SQLite3的方式。
res/raw/下靜態文件的讀取
在res/raw下存放words.xml文件。XML文件其實可以通過Android開發筆記之資源resource(下)
中所放置在res/xml中。本例僅用此說明放置在res/raw中文件讀取的方式。
1 |
<code
id= "code0" ><words>
|
2 |
<word
value= "lorem"
/> |
3 |
<word
value= "ipsum"
/> |
4 |
<word
value= "dolor"
/> |
5 |
<word
value= "sit"
/> |
6 |
<word
value= "amet"
/> |
7 |
…
… |
8 |
</words></code> |
源代碼如下:
01 |
public
class
Chapter23Test1 extends
ListActivity{ |
02 |
private
ArrayList<String> items = new
ArrayList<String>(); |
03 |
04 |
protected
void
onCreate(Bundle savedInstanceState) { |
05 |
super .onCreate(savedInstanceState); |
06 |
try { |
07 |
//
獲取該文件的InputStream,首先通過getResrouces()獲取資源對象,然後通過openRawResource()獲取指定文件的InputStream |
08 |
InputStream
in = getResources().openRawResource(R.raw.words); |
09 |
//解釋XML文件:從中獲取數據,放入ArrayList中。建立XML解析,將InputStream放入DOM文件中,通過樹狀結構NodeList獲取所需的數據。 |
10 |
DocumentBuilder
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); |
11 |
Document
doc = builder.parse(in, null );
|
12 |
NodeList
words = doc.getElementsByTagName( "word" ); |
13 |
14 |
for ( int
i = 0 ;
i < words.getLength(); i ++){ |
15 |
Element
node = (Element)words.item(i); |
16 |
items.add(node.getAttribute( "value" ););
|
17 |
}
|
18 |
} catch (Throwable
t){ |
19 |
Toast.makeText( this ,
"Exception:
"
+ t.toString(), Toast.LENGTH_LONG).show(); |
20 |
}
|
21 |
setListAdapter( new
ArrayAdapter<String>( this ,android.R.layout.simple_list_item_1,items));
|
22 |
} |
23 |
} |
應用私有文件讀取
對於文件,更重要的是支持讀寫操作,Android提供在應用目錄下的文件讀寫方式。下面是一個編輯器的例子,文件名稱爲notes.txt,位於應用文件目錄:/data/data/com.wei.android.learning/files/目錄下面。這個目錄是應用缺省的私有文件夾。編輯器在應用關閉,至於後臺的時候,講文本框的內容保存至文件,當有效時,從文件中讀取內容,恢復到編輯器中。也就是在onPause()時進行寫操作,onResume()時進行讀操作。第一次打開應用時,由於沒有找到文件,會返回一個錯誤,籍此我們可以跟蹤文件所在絕對路徑。下面是源代碼:
01 |
public
class
Chapter23Test2 extends
Activity{ |
02 |
private
EditText editor = null ;
|
03 |
private
static
String NOTES= "notes.txt" ;
|
04 |
protected
void
onCreate(Bundle savedInstanceState) { |
05 |
super .onCreate(savedInstanceState);
|
06 |
setContentView(R.layout.chapter_23_test2);
|
07 |
editor
= (EditText)findViewById(R.id.c23_editor); |
08 |
Button
button = (Button)findViewById(R.id.c23_close); |
09 |
button.setOnClickListener( new
View.OnClickListener() { |
10 |
public
void
onClick(View v) { |
11 |
//點擊button,執行finish(),即關閉activty,會觸發onPause(),在本例中會觸發寫操作
|
12 |
finish();
|
13 |
}
|
14 |
});
|
15 |
}
|
16 |
//onResume()即Activity有效時,進行讀文件操作,將文件的內容放置在EditText組件中
|
17 |
protected
void
onResume() { |
18 |
super .onResume();
|
19 |
20 |
try {
|
21 |
/*
openFileInput( String name)是android.content.ContextWrapper類的函數,可以在activity中直接調用,參數name,不能包含目錄分割符,即只能處理應用私有文件夾文件,獲得InputStream後,按常規java處理。如果需要訪問更多的地方,需要創建content privider,在以後學習*/
|
22 |
InputStream
in = openFileInput(NOTES); |
23 |
if(in
!= null){ |
24 |
BufferedReader
reader = new BufferedReader(new InputStreamReader(in)); |
25 |
String
str; |
26 |
StringBuffer
buf = new StringBuffer(); |
27 |
while((
str = reader.readLine()) != null){ |
28 |
buf.append(str
+ "\n"); |
29 |
}
|
30 |
in.close();
|
31 |
editor.setText(buf.toString());
|
32 |
}
|
33 |
}catch(Throwable
t){ |
34 |
Toast.makeText(this,"Exception:
" + t.toString(),5000).show(); |
35 |
}
|
36 |
}
|
37 |
//onPause()即Activity無效時,進行寫文件操作
|
38 |
protected
void onPause() { |
39 |
super.onPause();
|
40 |
try{
|
41 |
/*
openFileOutput (String name, int mode)中mode是打開模式,0或者MODE_PRIVATE爲缺省模式, MODE_APPEND表示在文件後增加,MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE是控制權限 */ |
42 |
OutputStreamWriter
out = new
OutputStreamWriter(openFileOutput(NOTES, 0 ));
|
43 |
out.write(editor.getText().toString());
|
44 |
out.close();
|
45 |
} catch (Throwable
t){ |
46 |
Toast.makeText( this , "Exception:
"
+ t.toString(), 5000 ).show();
|
47 |
}
|
48 |
}
|