各位看官们,大家好,上一回中咱们说的是Java常用类之文件操作的例子,这一回咱们继续说该例子。闲话休提, 言归正转。让我们一起Talk Android吧!
我们在上一回介绍了文件操作,主要是创建和删除文件,那么如何对文件中的内容进行读写操作呢?这时候就需要使用流了,这便是本章回的内容。
输入流与输出流
Java中的流比较多,我们常用的是输入流和输出流。
- 输入流表示从终端中输入数据到内存中,常用的输入终端是键盘,此外,从位于磁盘上的文件中读取数据也属于输入流。
- 输出流表示把内存中的数据输出到终端中,常用的输出终端是显示器,此外,把数据输出到磁盘上的文件中也属于输出流。
字节 流与字符流
有了输入流和输出流后,我们是不是可以使用它们操作文件了?暂时还不行,输入流和输出流只是表明数据的流动方向,我们还不知道流中的细节。这两种流可以通过字节或者字符的方式来操作流中的数据。因此,从这个角度来看,我们又把流分为字节流和字符流。通常情况下,我们使用字节流来操作文件,因为
系统中传输数据的单位为字节,所以使用字节流来操作文件,以便和系统操持一致。
输入流和输出流有了,字节流和字符流也有了,是不是可以使用它们操作文件了?是的,现在可以了。看官莫急,我们在实际的程序中还需要对字节流进行处理,目的是提高程序的性能。试想一下,每读取一个字节都要访问一次位于硬盘中的文件,那么这样的话,硬盘就不高兴了,因为读取硬盘的开销是比较大的,所以我们常用的做法是把字节数据放到缓冲区中,当缓冲区满了后再去访问硬盘,这样就可以减少访问硬盘的次数,进而提高程序性能。有看官提问:我们还要自己操作缓冲区吗?不需要,Java给我们提供了缓冲流,我们直接使用缓冲流就可以了。
以上这些内容介绍的都是抽象流,大家可能不容易理解,接下来我们介绍具体的流,它们都是Java提供的类,而且有具体的名字。现在请各大常用的流闪亮登场!
FileInputStream
该类属于输入流,用来把文件中的数据输入到内存中,在流中以字节为单位来操作数据,因此也可以叫它字节流。该类提供了read()
方法,我们可以使用该方法从文件中读取数据,该方法返回读取到的数据,数据类型为byte,如果到达文件末尾,它将返回-1。下面我们通过伪代码来演示一下:
while(-1 != (data = input.read())
{
byteArray[i] = (byte)data; i++;
} //这里面的input为FileInputStream类型的对象
FileOutputStream
该类属于输出流,用来把内存中的数据输出到文件中,在流中以字节为单位来操作数据,因此也可以叫它字节流。该类提供了write()
方法,我们可以使用该方法把数据写入到文件中。下面我们通过伪代码来演示一下:
output.write(byteArrary); //这里的byteArray是字节类型的数组,里面存放着将要被写入到文件中的数据
BufferedReader
该类属于输入流,用来把文件中的数据输入到内存中,在流中以字符为单位来操作数据,因此也可以叫它字符流。该类提供了read()
方法,我们可以使用该方法从文件中读取数据,该方法返回读取到的数据,数据类型为char,如果到达文件末尾,它将返回-1。该方法是重载方法:
read(char buf,int offset, int len)
该方法把文件中的字符读取到buf中,并且从buf的offset处开始存放len个字符,如果到达文件末尾,它将返回-1。
该类还提供了一个叫readLine()
的方法。该方法常用来从终端中读取数据,每次读取一行数据(遇到换行或者回车符时停止),它返回的数据类型为String
,如果到达文件末尾,它将返回-1。下面我们通过伪代码来演示一下:
while(-1 != (data = input.read())
{
charArray[i] = data; i++;
} //这里面的input为BufferedReader类型的对象。
while(null != (strData = input.readLine())
{
stringBuffer.append(strData);
} //这里面的input为BufferedReader类型的对象。
BufferedWriter
该类属于输出流,用来把内存中的数据输出到文件中,在流中以字符为单位来操作数据,因此也可以叫它字符流。该类提供了write(ch)
方法,我们可以使用该方法把字符ch写入到文件中。该方法是重载方法:
write(String buf,int offset, int len)
该方法把buf中的字符串写入到文件中,字符串从buf的offset处开始直到offset+len处结束。
该类还提供了一个叫newLine()
的方法,该方法常用来在文件中插入一个分隔符。下面我们通过伪代码来演示一下:
output.write(ch); //这里的ch是一个字符
output.write(str); //这里的str是一个字符串
output.write(buf,0,buf.length); //这里的buf是一个String类型的字符串
InputStreamReader
该类是转换流,常用来把输入类型的字节流转换为输入类型的字符流。因为缓冲流的操作对象是字符流,所以它经常和缓冲流配合使用。在进行流的转换时,使用它的构造器就可以。
OutputStreamWriter
该类是转换流,常用来把输出类型的字节流转换为输出类型的字符流。因为缓冲流的操作对象是字符流,所以它经常和缓冲流配合使用。在进行流的转换时,使用它的构造器就可以。
看官们,上面是理论知识,光说不练不是我们的风格,接下来我们通过具体的代码来演示如何使用流进行文件操作:
public class FileOp {
public static String filePath = "H:"+File.separator+"a.txt";
public static void main(String args[]) throws Exception
{
File file = new File(filePath);
FileInputStream inputStream = null;
FileOutputStream outputStream = null;
BufferedReader bufReader = null;
BufferedWriter bufWriter = null;
String strBuf = null;
String str = null;
int i = 0;
if( !file.exists() ) // must check the file state
{
if(new File(file.getParent()).exists())
file.createNewFile();
else
System.out.println("Parent dir is not exist");
}
else
System.out.println("File is "+filePath+"is existed");
inputStream = new FileInputStream(file);
outputStream = new FileOutputStream(file);
bufReader = new BufferedReader(new InputStreamReader(inputStream));
bufWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
for(i=1;i<4;++i)
{
strBuf = "The is line: "+i;
System.out.println("["+strBuf+"]"+" is written into file");
bufWriter.write(strBuf);
bufWriter.newLine();
}
bufWriter.flush(); // or bufWriter.close();
System.out.println("Reading content from file");
while(null !=(str = bufReader.readLine()))
System.out.println(str);
bufReader.close();
bufWriter.close();
inputStream.close();
outputStream.close();
}
}
上面的代码是一种典型的用法,大家可以参考,另外,我们没有使用流中所有的方法,大家可以结合理论部分的内容自己练习。下面是程序的运行结果,请大家参考:
[The is line: 1] is written into file
[The is line: 2] is written into file
[The is line: 3] is written into file
Reading content from file
The is line: 1
The is line: 2
The is line: 3
从上面结果中可以看到,我们成功地对文件进行了读写操作。
看官们,最后我们说一下文件操作时的注意事项,单独列出来进行说明,就是希望能够引起大家注意:
- 1.使用流时都会有I/O异常,因此需要我们进行异常处理。上面的程序中,我们为了方便,直接抛出异常,在实际项目中不能这样处理。
- 2.使用完流后都需要关闭流,以释放相关的系统资源。
- 3.最好使用字节流来操作数据,并且配合缓冲流,这样可以提高文件读写效率。
各位看官,关于Java常用类之文件操作的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!