java复习:IO流基础字符流
2015-11-04 16:33
661 查看
1、 IO概述
(1)概述IO流:即InputOutput的缩写。是用来处理设备间(内存、硬盘)的数据传输。
(2)IO流的常用基类:
a.字节流的抽象基流:InputStream和OutputStream
b.字符流的抽象基流:Reader和Writer
注:此四个类派生出来的子类名称都是以父类名作为子类名的后缀,以前缀为其功能;如InputStream子类FileInputStream;Reader子类FileReader
(2)特点:
1)IO流用来处理设备间的数据传输。
2)Java对数据的操作是通过流的方式。
3)Java用于操作流的对象都在IO包中。
4)流按操作数据分为两种:字节流和字符流。
5)流按流向分为:输入流和输出流。
注意:流只能操作数据,而不能操作文件。
2、字符流 FileWriter和FileReader
字符流中的对象融合了编码表。使用的是默认的编码,即当前系统的编码。字符流只用于处理文字数据,而字节流可以处理媒体数据。既然IO流是用于操作数据的,那么数据的最常见体现形式是文件。2.1 输入流
查看API,找到一个专门用于操作文件的Writer子类对象:FileWriter。 后缀是父类名。前缀名是流对象的功能。该流对象一被初始化,就必须有被操作的文件存在。
(1) IO输入流的基本用法和IO的异常处理
import java.util.*; import java.io.*; class FileWriterDemo1 { public static void main(String[] args) { FileWriter fw=null;//在外部建立引用,在内部建立对象。如果都 4000 在内部建立在finally中就找不到fw try { fw=new FileWriter("K://demo.txt"); fw.write("安徽"); } catch (IOException e)//如果创建的为“K://demo.txt”则系统找不到指定的路径就会报告异常NUllPointEXception { System.out.println(e.toString()); } finally { try { if(fw!=null)//如果fw为空的情况下,不应该执行关闭的操作,不应调用close()。如果有5个流对象,得分别关闭5次。 fw.close(); } catch (IOException e) { System.out.println(e.toString()); } } } }
(2) 文件的续写
//需求:文件的续写,假如文件中已经有内容“原来文件内容”;添加新的信息文件续写 import java.util.*; import java.io.*; class FileWriterDemo2 { public static void main(String[] args) { FileWriter fw=null;//在外部建立引用,在内部建立对象。如果都在内部建立在finally中就找不到fw try { fw=new FileWriter("demo.txt",true); fw.write("续写\r\n信息"); } catch (IOException e)//如果创建的为“K://demo.txt”则系统找不到指定的路径就会报告异常NUllPointEXception { System.out.println(e.toString()); } finally { try { if(fw!=null)//如果fw为空的情况下,不应该执行关闭的操作,不应调用close()。如果有5个流对象,得分别关闭5次。 fw.close(); } catch (IOException e) { System.out.println(e.toString()); } } } }
2.2 输出流
查看API,找到一个专门用于操作文件的Writer子类对象:FileWriter。 后缀是父类名。前缀名是流对象的功能。该流对象一被初始化,就必须有被操作的文件存在。
举例说明:
//需求:读取文件的内容,并打印到控制台上 import java.util.*; import java.io.*; class FileReaderDemo3 { public static void main(String[] args) { FileReader fr=null; try { fr=new FileReader("demo.txt"); /************************第一种***************************/ while (true) { int ch=fr.read(); if (ch==-1) break; System.out.print((char)ch); } /************************第二种***************************/ while (true) { int ch=0; while ((ch=fr.read())!=-1) { System.out.print((char)ch); } break; } /************************第三种***************************/ char[] buf=new char[3]; int num=0; while ((num=fr.read(buf))!=-1) { System.out.print(new String(buf,0,num)); } } /**********************************************************/ catch (IOException e) { System.out.println(e.toString()); } finally { try { fr.close(); } catch (IOException e) { System.out.println(e.toString()); } } } }
2.3 拷贝文件
//需求:demo.txt中的文本信息拷贝到copydemo.txt中去 import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; class CopyDemo4 { public static void main(String[] args) { private static final int BUFFER_SIZE=1024; FileWriter fw=null; FileReader fr=null; try { fw=new FileWriter("Copydemo.txt"); fr=new FileReader("demo.txt"); char[] buf=new char[BUFFER_SIZE]; int num=0; while ((num=fr.read(buf))!=-1) { fw.write(buf,0,num); } } catch (IOException e) { System.out.println(e.toString()); } finally { try { if (fr!=null) fr.close(); } catch (IOException e) { System.out.println(e.toString()); } try { if (fw!=null) fw.close(); } catch (IOException e) { System.out.println(e.toString()); } } } }
3、字符流缓冲区
3.1 BufferedReader和BufferedWriter简介注:
(1)假如缓冲区是为了提高效率,但是真正的操作还是FileWriter(),关闭缓冲区就是关闭缓冲区的流对象。
(2)newLine()写入一个行分隔符,具有跨平台性。
public String readLine() throws IOException
读取一个文本行。通过下列字符之一即可认为某行已终止:换行 (‘\n’)、回车 (‘\r’) 或回车后直接跟着换行。
返回:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
3.2 缓冲区文件复制
import java.io.*; class BufCopyDemo1 { public static void main(String[] args) { BufferedWriter bufw=null; BufferedReader bufr=null; try { bufw=new BufferedWriter(new FileWriter("copydemo.txt")); bufr=new BufferedReader(new FileReader("demo.txt")); String line=null; while ((line=bufr.readLine())!=null) { bufw.write(line); bufw.newLine(); bufw.flush(); } } catch (IOException e) { throw new RuntimeException("读写失败"); } finally { try { if (bufr!=null) bufr.close(); } catch (IOException e) { throw new RuntimeException("读写关闭失败"); } try { if (bufw!=null) bufw.close(); } catch (IOException e) { throw new RuntimeException("读写关闭失败"); } } } }
3.3 自定义的缓冲区文件内容的复制
/* 需求:既然明白了readLine()的原理,可以自定义一个类中包含一个功能和readLine()一致的方法来模拟BufferedReader() */ import java.io.*; class BufCopDemo2 { public static void main(String[] args)throws IOException { FileReader fr=new FileReader("demo.txt");// MyBufferedReader mybuf=new MyBufferedReader(fr); String line=null; while ((line=mybuf.myReadLine())!=null) { System.out.println(line); } mybuf.myClose(); } } class MyBufferedReader { private FileReader r;//为了流对象作用于整个类,需要定义成员变量 MyBufferedReader(FileReader r) { this.r=r; } /*定义一个临时容器,原BufferedReader中定义的是字符数组,但是需要使用的指针概念.可以使用StringBuilder容器来存储,因为最终还是将数据变成字符串*/ public String myReadLine() throws IOException { StringBuilder sb=new StringBuilder(); int ch=0; while ((ch=r.read())!=-1) { if (ch=='\r') continue; if (ch=='\n') return sb.toString(); else sb.append((char)ch); } if (sb.length()!=0) return sb.toString(); return null; } pu ceb6 blic void myClose() throws IOException { r.close(); } }
3.4 LineNumberReader
import java.io.*; class LineNumberReaderDemo { public static void main(String[] args) throws IOException { FileReader fr=new FileReader("demo.txt"); LineNumberReader lnr=new LineNumberReader(fr); String line=null; lnr.setLineNumber(100); while ((line=lnr.readLine())!=null) { System.out.println(lnr.getLineNumber()+">>"+line); } lnr.close(); } }
4、IO流的装饰设计模式
4.1 基本概述装饰设计模式:当想要对已有对象进行功能增强时,可以定义类将已有对象传入,基于已有对象的功能并提高加强功能,那么自定义的类称为装饰类。
装饰类通常会通过构造方法接受被装饰的对象,并基于被装饰的对象提供更强的功能。
例如:
一个人具有基本的功能吃饭
class Person { public static void eat() { System.out.println("吃饭"); } }
进行装饰,功能增强后:
class SuperPerson { private Person p; SuperPerson(Person p) { this.p=p; } public static void supereat() { System.out.println(“开胃酒”); p.chifan(); System.out.println("甜点"); } } class Demo { public static void main(String[] args) { Person p=new Person(); SuperPerson sp=new SuperPerson(p); sp.superchifan(); } }
4.2 继承和装饰的区别
首先有一个继承体系:Writer |--TextWriter:用于操作文本 |--BufferTextWriter:加入了缓冲技术的操作文本的对象,对操作的动作进行效率的提高。 |--MediaWriter:用于操作媒体 |--BufferMediaWriter:加入了缓冲技术的操作媒体的对象,对操作的动作进行效率的提高。
以上方式并不理想,如果这个体系需要再进行功能扩展,又多了更多流对象。这样就会发现只为提高功能,导致继承体系越来越臃肿,不够灵活。
解决问题:
既然加入的都是同一种技术–缓冲。
将缓冲进行单独的封装,哪个对象需要缓冲就将哪个对象和缓冲关联。
class BufferedWriter extends Writer { BufferedWriter(Writer w){} }
装饰比继承更加的灵活。避免了继承体系臃肿,而且降低了类与类之间的关系。但是装饰类和被装饰类必须所属同一个接口和父类。装饰类因为增强已有对象。具备的功能和已有也是相同的,只不过提供了更强的功能。
举例说明:
/**************************************************************************** 自定义一个读取缓冲区类,模拟一BufferedReader 分析:缓冲区无非就是封装了一个数组,并对外提供了更多的方法对数组进行访问, 其实这些方法最终操作都是数组的角标。 缓冲的原理:其实就是从源中获取一批数据到缓冲区中,再从缓冲区不断地取出一个 一个数据。在此次取完后,再从源中继续取一批数据进缓冲区,当源中的数据取完时, 用-1作为结束标记. ****************************************************************************/ import java.io.*; class MyBufferedReader { private Reader r; private char[] buf = new char[1024]; //定义一个数组作为缓冲区 private int pos = 0; //定义一个指针用于操作这个数组中的元素,当操作到最后一个元素后,指针应该归零 private int count = 0; //定义一个计数器用于记录缓冲区中的数据个数,当该数据减到0,就从源中继续获取数据到缓冲区中 MyBufferedReader(Reader r) { this .r = r; } public int myRead() throws IOException//该方法从缓冲区中一次取一个字符 { if (count == 0)//从源中获取一批数据到缓冲区中,需要先做判断,只有计数器为0时,才需要从源中获取数据 { count = r.read(buf); pos = 0;//每次获取数据到缓冲区后,角标归零 } if (count < 0) return -1; char ch = buf[pos]; pos++; count--; return ch; } public String myReadLine() throws IOException { StringBuilder sb = new StringBuilder(); int ch = 0; while ((ch = myRead()) != -1) { if (ch == '\r' ) continue ; if (ch == '\n' ) return sb.toString(); sb.append(( char )ch);//将从缓冲区读到的字符,存储到缓存行数据的缓冲区中 } if (sb.length() != 0) { return sb.toString(); } return null ; } public void myClose() throws IOException { r.close(); } } class MyBufferedReaderDemo { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("buf.txt" ); MyBufferedReader bufr = new MyBufferedReader(fr); String line = null ; while ((line = bufr.myReadLine()) != null) { System.out.println(line); } bufr.myClose(); } }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统