------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ---------
学习概述:Java IO流也是Java重要基础知识,学习Java IO流体系:包括输出流和输入流两大体系以及它们的子类,以及File类的使用方法
学习目标:要对Java Io流体系做到胸有成竹,哪怕不能完全挤出所有的流对象,对于大体的框架也要梳理清楚,能够做到知道在什么时候用哪一种流对象最合适。
综述:java IO流体系
1.IO(Input Output)流
(1)用来处理设备之间的数据传输
(2)Java对于数据的操作都是通过流的方式
(3)所有的操作流对象都在IO包
(4)流操作数据分为两种:字节流和字符流,按数据流动方向分为输入流和输出流
(5)字节流和字符流均有两个抽象基类,其中字节流为(InputStream,OutputStream),字符流为(Reader和Writer),分别代表了对数据的那种操作那就是读和写。
注意:有这四个基类派生出来的子类都是以其父类作为子类的后缀名。
2.文件操作
数据最常见的体现形式就是文件,所以对于文件操作是极其重要的一方面。
(1)用字符流对象实现文件操作,我们创建一个FileWriter对象,该对象一初始化就必须要明确被操作文件,而且该文件会被创建到指定目录下,特别要注意一点:如果已经存在同名文件,那么原来的文件就会被覆盖,如果不希望这种情况发生,那么要采用这种方法,FileWriter 分为= new FileWriter("文件名",true);
重点关注:flush()和close()的区别。close()表示关闭流资源之前会刷新,将数据刷到目的地。然后流将会关闭而flush()刷新后,该流仍可继续使用。
本质:Java调用windows的系统资源完成数据的建立,所以你使用之后要释放资源,所以close()必须要手动完成。
(2)对IO异常的完整处理
标准的IO异常处理,在关闭前要对IO流是否为空进行判断,否则会出现空指针异常问题。然后还要注意分别去关闭已经打开的IO流,如如下代码所示
finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
// There is nothing we can do if close fails
}
if (out != null)
try {
out.close();
} catch (IOException ex) {
// There is nothing we can do if close fails
}
}
}
3.文件的续写
关注问题:换行问题,记事本不识别\n如果采用这种方式,那么记事本文件会出现乱码,在windows中要采用\r\n这种形式
4. 字符流缓冲区
缓冲流的关键字:Bufferred
知识要点:(1)缓冲区的出现大大提高了对数据的读写效率
(2)他们的对应类分别是:BufferedWriter,BufferedReader
(3)缓冲区必须要结合流才能使用
(4)由于流的出现,在流的基础上对流的功能进行了增强
(5)只要用到缓冲区就必须要使用flush方法,然后采用close方法
实现原理:封装了一个数组,然后直接对对象操作,当读到换行符时,就将数组中的数据移出,然后再继续读下一行
使用要点:Java IO流体系比较复杂,很容易产生混乱,对于缓冲流我们可以这么理解:缓冲流可以看做操作IO流的工具类,这个工具类也是一个流,所以使用缓冲流必须结合流出现才行,因为这个流存在的价值就是用来操作流的,没有了流,它要操作什么呢? 使java用要点:Java IO流体系有很多类,很同意让人感到很混乱
5.关于readline()方法
readline()是缓冲字符流一个很重要的方法,该方法用来完成对字符和数组的逐行读取,该方法读到最后会返回null,所以为了不影响输出效果,要在该方法前加入判断因子(line=readline())!=null)。readline实际上还是基于InputStream的read方法,其实最终都是在硬盘上一个一个读取。
课后练习:
自己实现缓冲区MyBufferedReader
mport java.io.IOException;
/*
*明白了BufferedReader类中特有方法readLine的原理后
*可以自定义一个类中包含一个功能和readLine一致的方法。
*来模拟一下BufferedReader
*/
class MyBufferedReader
{
//因为要基于FileReader的方法,所以要把FileReader方法传进来
//因为要作用于整个类的话,所以定义一个成员变量
private FileReader r ;
//一初始化就有一个流对象进来
MyBufferedReader(FileReader r)
{
this.r = r;
}
//可以一次读一行的方法
public String myReadLine()throws IOException
{
//定义一个临时容器,原BufferReader中封装的是字符数组。
//为了演示方便。定义一个StringBuilder容器。因为最终还是要将数据变成字符串
StringBuilder sb = new StringBuilder();
int ch = 0;
while((ch=r.read())!=-1)
{
//如果读到的是\r就继续循环
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
//读一个字符就存到缓冲区当中
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
public void myClose()throws IOException
{
r.close();
}
}
class MyBufferedReaderDmeo
{
public static void main(String[] args)throws IOException
{
//创建一个读取对象
FileReader fr = new FileReader("buf.txt");
//创建一个读的流缓冲区对象
MyBufferedReader br = new MyBufferedReader(fr);
//演示一行一行读的方法readLine();
String line = null;
while((line = br.myReadLine())!=null)
{
System.out.println(line);
}
//关闭缓冲区
br.myClose();
}
}