由于Android使用的文件系统是基于Linux的文件系统,这就允许程序开发人员建立和访问程序自身的私有文件,也可以访问保存在资源目录中的原始文件和XML文件,还可以保存文件在SD卡等外部存储设备中。
本文先介绍下内部存储
Android系统允许应用程序创建仅能够自身访问的私有文件,文件保存在设备的内部存储器上的/data/data/<package name>/files目录中。和传统的Java中实现I/O的程序类似,在Android中,其提供了openFileInput 和 openFileOutput 方法读取设备上的文件。
1.openFileOutput()
openFileOutput()方法打开的应用程序私有文件,为写入数据做准备。在默认情况下,写入的时候会覆盖原文件内容,如果想把新写入的内容附加到原文件内容后,则可以指定其mode为Context.MODE_APPEND;如果指定的打开文件不存在时,则创建一个新的文件。默认情况下,使用openFileOutput方法创建的文件只能被其调用的应用使用,其他应用无法读取这个文件。
openFileOutput()方法的语法格式如下:
代码清单7-10 openFileOutput()
public FileOutputStream openFileOutput(String name, int mode)
其中,第1个参数是文件名称,这个参数不可以包含描述路径的斜杠,也就是说,它并不允许我们去修改保存文件的路径;第2个参数是操作模式;方法的返回值是FileOutputStream类型。
关于第2个参数——操作模式来讲,Android系统支持4种文件操作模式,具体如表7-1所示。
表7-1 Android系统支持4种文件操作模式
模式 |
说明 |
MODE_PRIVATE |
私有模式,缺陷模式,文件仅能够被文件创建程序访问,或具有相同UID的程序访问 |
MODE_APPEND |
追加模式,如果文件已经存在,则在文件的结尾处添加新数据 |
MODE_WORLD_READABLE |
全局读模式,允许任何程序读取私有文件 |
MODE_WORLD_WRITEABLE |
全局写模式,允许任何程序写入私有文件 |
使用openFileOutput()方法建立新文件的示例代码如代码清单7-11所示。
代码清单7-11 openFileOutput()建立新文件
//建立文件的名称fileDemo.txt
String FILE_NAME = "fileDemo.txt";
//使用openFileOutput()方法以私有模式建立文件
FileOutputStream fos = openFileOutput
(FILE_NAME,Context.MODE_PRIVATE);
String text = "Some data";
//将数据写入文件
fos.write(text.getBytes());
//将所有剩余的数据写入文件
fos.flush();
//关闭FileOutputStream
fos.close();
注意:
为了提高文件系统的性能,一般调用write()函数时,如果写入的数据量较小,系统会把数据保存在数据缓冲区中,等数据量累积到一定程度时再一次性地写入文件中。由此可知,在调用close()函数关闭文件前,务必要调用flush()函数,将缓冲区内所有的数据写入文件。
2.openFileInput()
openFileInput()方法打开应用程序私有文件为从其中读取数据而做准备。openFileInput()方法的语法格式如代码清单7-12所示。
代码清单7-12 openFileInput()
public FileInputStream openFileInput (String name)
第1个参数是文件名称,同样不允许包含描述路径的斜杠。
使用openFileInput ()方法打开已有文件的示例代码如代码清单7-13所示。
代码清单7-13 openFileInput()打开已有文件
String FILE_NAME = "fileDemo.txt";
FileInputStream fis = openFileInput(FILE_NAME);
byte[] readBytes = new byte[fis.available()];
while(fis.read(readBytes) != -1){
}
上面的两部分代码在实际使用过程中会遇到错误提示,在实际使用过程中,应该使用try/catch捕获可能产生的异常来避免因为文件操作遇到的各种问题而导致的操作失败。
InternalFileDemo示例用来演示在内部存储器上进行文件写入和读取,示例的用户界面如图7-3所示。

图7-3 InternalFileDemo示例用户界面图
InternalFileDemo示例的核心代码如代码清单7-14所示。
代码清单7-14 InternalFileDemo示例的核心代码
OnClickListener writeButtonListener = new OnClickListener() {
@Override
public void onClick(View v) {
FileOutputStream fos = null;
try {
if (appendBox.isChecked()){
fos = openFileOutput(FILE_NAME,Context.MODE_APPEND);
}else {
fos = openFileOutput(FILE_NAME,Context.MODE_PRIVATE);
}
String text = entryText.getText().toString();
fos.write(text.getBytes());
labelView.setText("文件写入成功,写入长度:"+text.length());
entryText.setText("");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
finally{
if (fos != null){
try {
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
};
OnClickListener readButtonListener = new OnClickListener() {
@Override
public void onClick(View v) {
displayView.setText("");
FileInputStream fis = null;
try {
fis = openFileInput(FILE_NAME);
if (fis.available() == 0){
return;
}
byte[] readBytes = new byte[fis.available()];
while(fis.read(readBytes) != -1){
}
String text = new String(readBytes);
displayView.setText(text);
labelView.setText("文件读取成功,文件长度:"+text.length());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
};
程序运行后,可以在/data/data/cn.com.farsight.InternalFileDemo/files/目录下,找到新建立的fileDemo.txt文件: fileDemo.txt从文件权限上进行分析,“-rw-rw---”表明文件仅允许文件创建者和同组用户读/写,其他用户无权使用;文件内保存的数据为“Some data”,其大小为9个字节。