Android数据存储与IO之二(File存储之openFile)
介绍了Android提供的SharePreferences接口及其提供的方法后,我们发现,SharePreferences仅仅适用于存储一些简单的基本数据类型比如说配置信息等等,且其存储格式单一为XML,存储信息的单一类型以及存储格式的单一局限了其使用的范围。所以Android提供了另外一种数据存储及IO方式----File 存储。
首先,使用File存储我们要先打开应用存储的数据文件夹的IO流,Context提供了如下的方式来打开:
FileInputStream openFileinput(String name)
FileOutputStream openFileOutput(String name,int mode)
以上两个方法分别用于打开文件的输入流与输出流,其输入与输出为原始字节流,其中第一个参数为IO的对象文件的名称及格式,如我要读取一个名为“test”的txt文件,那么name应为“test.txt”。我们不需要在name中给定文件的绝对路径因为openFile方法默认打开“/data/data/files/”路径下的文件。很明显,输出流函数比输入流函数多了一个mode参数,这是因为输出流函数需要设定其操作的文件的访问权限,mode参数支持如下值:
MODE_PRIVATE 为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPEND
MODE_APPEND 以追加方式,当前应用程序本身可以向文件中添加内容而不覆盖原有内容
MODE_WORLD_READABLE 文件可以被其他应用程序读取
MODE_WORLD_WRITABLE 文件可以被其他应用程序写入,注意,其他应用程序写入时会覆盖原有内容。
如果希望文件被其他应用读和写,可以传入:
openFileOutput(name, Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);
此外,Context还提供了如下几个方法来访问应用程序的数据文件夹
getDir(String name,int mode) 返回/data/data/<package>/下的指定名称的文件夹File对象,如果该文件夹不存在则用指定名称创建一个新的文件夹。注意此处的mode仅仅表示了此文件夹的访问权限并不包括文件夹的子文件及子文件夹的访问权限
File getFileDir() 返回/data/data/youPackageName/files的File对象。
String[]fileList() 获得数据文件夹下的所有文件,返回的是String[]对象
deleteFile(String name) 删除files下的name对应的指定文件
File getCacheDir(),该方法返回/data/data/<package>/cache的File对象,cache为缓存文件夹。
好了,现在文件输入输出流已经被打开,接下来就是读取与写入数据,File的IO为字节流,对于读取,Android提供了
public int read(byte[ ] byte)函数,读取成功时返回读取的字节长度,读取失败返回-1,因为得到的是字节流,我们可以很方便的将他们转化为我们需要的数据形式。
对于写入,Android提供了write(byte[ ] byte)方法,同样你也可以使用PrintStream与PrintWriter打印方法,前者操作字节流,后者操作字符流(java的一个字符(char)是16bit的,一个BYTE是8bit的 )且在很多地方可以通用。关于write与read方法的使用可以参考下面的代码
注意,当读取与写入结束后,我们一定要调用close方法关闭流,否则会导致流一直被占用,造成资源浪费!!
说了这么多,现在我们利用penFileinput和openFileOutpu进行IO流操作
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
write("哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈");
TextView text=(TextView)findViewById(R.id.test);
text.setText(read());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void write(String content){
try {
FileOutputStream fos=this.openFileOutput("test07.txt", Context.MODE_APPEND);//打开输出流
PrintStream ps=new PrintStream(fos);//将FileOutputStream包装成PrintStream
ps.println(content);//输出文件内容
ps.close();//关闭流,非常重要
} catch (Exception e) {
e.printStackTrace();
}
}
public String read(){
try {
FileInputStream fis=this.openFileInput("test07.txt");//打开输入流
byte[] buff=new byte[1024];//建立byte数组
int hasRead=0;
StringBuffer str=new StringBuffer();//生成缓冲字符串
while((hasRead=fis.read(buff))>0){//read函数每次读取buff数组长度的byte,存入buff数组中
str.append(new String(buff,0,hasRead));//将字节数组转化成字符串
}
fis.close();
return str.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "阿西吧";
}
}
哈哈哈哈哈哈,就写到这里了,接下来一篇就是如何利用外部存储区域进行IO流了