今天我们学习在安卓系统下对文件进行读写操作。应用程序的界面如图1所示。
图1 文件读写界面
通过Eclipse的“File Explorer”查看操作的文件,如图2所示。
图2 file_test.bin文件属性
1 界面构建
在Eclipse中新建一个名为“FileTest”的安卓程序项目。接下来在界面布局xml文件中添加两个EditText控件和两个Button控件。将用于写入的EditText的ID设置为“input_EditText”,将用于写入的Button的ID设置为“input_Button”,将用于读出的EditText的ID设置为“output_EditText”,将用于读出的Button的ID设置为“output_Button”。
2 文件写入
在MainActivity类的定义中,为该类添加一个私有的方法write(),用于文件的写入。在该方法中,由于用到操作文件的方法,因此需要使用异常处理。
2.1 异常处理
privatevoid write(String content)
{
try
{
..........
}
catch(Exception e)
{
e.printStackTrace();
}
}
异常处理用关键字try和catch来实现。try程序块若是有异常发生时,程序的运行便中断,并抛出异常类所产生的对象。抛出的对象如果属于catch()括号内欲捕获的异常类,则catch会捕捉此异常,然后进到catch的块里继续运行。
在以上代码中,catch欲捕捉的异常类是Exception,当try中的代码抛出Exception异常时,调用该异常类的printStackTrace()方法将异常信息显示出来。
2.2 写入文件
在try程序块中利用FileOutputStream类实现文件的写入。
2.2.1FileOutputStream类对象的创建
首先,定义FileOutputStream类的对象。
FileOutputStream fos = openFileOutput(FILE_NAME,MODE_APPEND);
FileOutputStream类表示指定的输出流(OutputStream),在文件系统中,使用该流将数据写入到文件中。该类可以通过Context类的openFileOutput()方法获得。该方法的格式为
public abstract FileOutputStreamopenFileOutput(String name, int mode)
throws FileNotFoundException
其中,方法的参数name表示要打开的文件名;参数mode表示打开文件的方式。方法的返回值是FileOutputStream类的对象,如果在该方法执行的过程中出现异常,则抛出FileNotFoundException。需要注意的是,openFileOutput类只能打开并写入应用程序包的私有文件,这种私有文件使用安卓系统中“文件管理”app是看不到的。使用以下代码实现FileOutputStream类对象的创建。
FileOutputStream fos = openFileOutput(FILE_NAME,MODE_APPEND);
其中,FILE_NAME是自定义的变量,在MainActivity类定义中完成:
final StringFILE_NAME ="file_test.bin";
openFileOutput方法的第二个参数MODE_APPEND表示如果FILE_NAME指定的文件存在,则向该文件中写入数据时,将数据写入到文件的最后,而不是将文件清空后重新写入。生成的FileOutputStream类的对象就保存在fos中。
2.2.2 PrintStream类对象的创建
在生成了FileOutputStream类的对象之后,利用该对象生成PrintStream类的对象。PrintStream类绑定了FileOutputStream类,并且可以很方便的实现写入数据等功能。通过该类的构造函数创建对象,其构造函数格式为
publicPrintStream(OutputStream out)
其中,参数out即为绑定的OutputStream类的对象。通过以下代码实现PrintStream类的创建
PrintStream ps =new PrintStream(fos);
其中,fos是FileOutputStream类的对象,生成的PrintStream类的对象就保存在ps中。
2.2.3 文件的写入
通过获取到的PrintStream类的对象ps实现文件的写入。代码如下所示
1 ps.println(content);
2 ps.close();
其中,第1行中的println()方法的作用是将指定的字符串写入到其绑定的输出流中,再由输出流将字符串写入到指定的文件中,content是write()方法的参数;第2行代码的作用是关闭PrintStream。
3 文件读取
在MainActivity类的定义中添加一个名为read()的方法,在该方法中使用异常处理。
private String read()
{
try
{
}
catch(Exception e)
{
e.printStackTrace();
}
returnnull;
}
3.1FileInputStream类
通过FileInputStream类实现从文件中读取数据。该类通过openFileInput()方法获取。
FileInputStream fis = openFileInput(FILE_NAME);
其中,FILE_NAME是定义的文件,创建的FileInputStream类的对象就保存在fis中。
3.2 文件的读取
通过以下代码实现文件的读取
1 byte[] buff =newbyte[1024];
2 int hasRead = 0;
3 StringBuilder strB =new StringBuilder("");
4 while((hasRead=fis.read(buff)) > 0)
5 {
6 strB.append(new String(buff, 0, hasRead));
7 }
其中,第1行定义了一个字节数组,该数组中元素的个数为1024个,即假定了文件的大小不超过1024字节;第2行定义了一个int类型的变量,用来表示从文件中读取数据的字节数;第3行通过new关键字定义了StringBuilder类的对象,通过该类可以很方便的实现对字符串的创建和修改等操作;第4-7行实现了对文件的读取功能,其中第4行使用while语句的目的是读取多次,保证指定文件中的数据被全部读出,如果文件中的数据没有被全部读出,则read()方法的返回值hasRead不为零,则继续读取,否则为零,停止读取;第6行中通过StringBuilder类的append()方法将读取到的数据进行组合,其中append()方法的参数是String类型,而从文件中读取的数据是byte数组,因此需要进行转换,第6行中append()的参数调用了String类型的构造函数,其格式为
publicString(byte[] data,int start,int length)
其中,data表示要转化为String的byte数组,start表示从数组的哪个位置开始转化,length表示要转换的字节数量。
4 按键点击事件监听的实现
接下来就是对“读取”和“写入”两个按键的点击事件进行监听。
4.1 监听“写入”按键的点击
通过以下代码实现对“写入”按键的点击监听。
1 write_Button.setOnClickListener(new OnClickListener()
2 {
3 @Override
4 publicvoid onClick(View source)
5 {
6 write(write_EditText.getText().toString());
7 write_EditText.setText("");
8 }
9 });
其中,第1行中的write_Button是通过findViewById()方法获取到的“写入”按键的对象;第6行中的write是在“2文件写入”中定义的方法,该方法的参数write_EditText是通过findViewById()方法获取到的用于写入的EditText控件对象。
4.2 监听“读取”按键的点击
通过以下代码实现对“读取”按键的点击监听。
1 read_Button.setOnClickListener(new OnClickListener(){
2 @Override
3 publicvoid onClick(View v)
4 {
5 read_EditText.setText(read());
6 }
7 });
其中,第1行的read_Button是通过findViewById()方法获取到的“读取”按键的对象;第5行中的read_EditText是通过findViewById()方法获取到的用于读取的EditText控件的对象,read()方法是在“3文件读取”中定义的read()方法。