一 数据流概念
1 数据流
Java中把数据源和不同程序间的数据传输操作都抽象表述为流(stream),已实现相对统一和简单的输入\输出操作。传输中的数据也像流水一样,称为数据流。
2 IO数据流的分类方式
数据流分为输入流和输出流,输入流只能读不能写,输出流只能写不能读。(从程序角度确定出入方向,数据从程序控制的内存空间传送到外部空间称为输出,数据从外部空间传送到程序控制的内存区称为输入。)
3 缓冲流(Buffered Stream)
对数据流的每次操作都是以字节为单位进行的,既可以向输出流写入一个字节,也可从输入流中读取一个字节。显然效率太低,通常使用缓冲流,即为一个流配置一个缓冲区,一个缓冲区就是专门传送数据的一块内存。
4 数据源(Data Sourcc):是指那些能够提供数据的地方,包括键盘、磁盘文件、网络接口等。
5 数据宿(Data Sink):指能够接收数据的地方,可以是磁盘文件、网络接口以及显示器、打印机等外部设备。(数据宿也可认为是数据传输的目的地)
二 节点流和处理流
根据数据流所关联的是数据源还是其他数据流,可分为节点流(Node Stream)和处理流(Processing Stream)
节点流可以从/向一个特定的地方读/写数据。
处理流是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现增强的数据读/写功能,处理流并不直接连接到数据源。
三 字符流
1 字符输入流Reader
Reader类为所有面向字符的输入流的超类,声明为java.io中的抽象类。
public int read():读取一个字符,返回的是读到的那个字符。如果读到流的末尾,返回-1。
public int read(char[] cbuf):将读到的字符存入指定的数组中,返回的是实际读取的字符数。如果读到流的末尾,返回-1。
public abstract int read(char[] cbuf,int off,int len):将读到的字符存入数组的指定位置(off),每次最多读len个字符,返回实际读取的字符数。如果读到流的末尾,返回-1。
close():读取字符其实用的是window系统的功能,使用完毕后,进行资源的释放。
2 字符输出流writer
writer类为所有面向字符的输出流的超类,声明为java.io中的抽象类。
public void write(int c):将一个字符写入到流中。
public void write(char[]):将数组中的字符依次写出。
public abstract void write(char[] bcbuf,int off,int len):将数组中下标off开始的len个字符写出。
public void write(String):将一个字符串写入到流中。
public abstract void flush():刷新流,将流中的数据刷新到目的地中,流还存在。
public abstreact void close():关闭资源,关闭前会先调用flush,刷新流中的数据去目的地,然后流关闭。
3 FileWriter的使用
该类没有特有的方法。只有自己的构造数。
该类特点:
1.用于处理文本文件。
2.该类中有默认的编码表,
3.该类中有临时缓冲。
构造函数
publicFileWriter(Stringfilename);//调用系统资源,在指定位置,创建一个文件。注意:如果该文件已存在,将会被覆盖。
例子:
import java.io.*; public class Demo1 {
/** * @param args */ public static void main(String[] args)throws IOException { // TODO Auto-generated method stub //创建输出流对象 FileWriter fw=new FileWriter("demo.txt"); char ch='中'; char arr[]={'a','b','','c'}; string str="program"; fw.write(ch); fw.write(arr); fw.write(arr,1,2); fw.write(str,3,3); fw.write("helo world"); fw.flush(); fw.write("java"); fw.close(); }
} |
4. FileReader的使用
用于读取文本文件的流对象。构造函数:在读取流对象初始化的时候,必须要指定一个被读取的文件。
public FileReader(String filename);//如果该文件不存在会发生FileNotFoundException
例子:
import java.io.*; public class Demo4{ public static void main(String[] args){ FileReader fr=null; char[] arr=new char[1024]; try{ fr=new FileReader("e:/a/demo.txt");//读取可能抛异常 int len=fr.read(arr); while(len!=-1){ System.out.print(new String(arr,0,len)); len=fr.read(arr);//实际读到的字数
} System.out.println(); }catch(IOException e){ System.out.println(e.toString()); }finally{ if(fr!=null){ try{ fr.close(); }catch(IOException e){ System.out.println(e.toString()); }
} } } } |
四 缓冲字符流
1 缓冲字符流
采用缓冲处理是为了提高效率,如果没有缓存,例如FileReader对象,每次调用read()方法进行读操作时,都会直接去文件中读取字节,转换成字符并返回,这样频繁的读取文件效率很低。
原理就是将数组进行封装。
缓冲的字符流的出现提高了对流的操作效率,缓冲的存在是为了增强流的功能,因此在建立缓冲的字符流对象时,要先有流对象的存在。
2 字符缓冲输入流BufferedReader类
构造方法:
public BufferedReader(Read in):创建一个使用默认大小输入缓冲区的缓冲字符输入流。
public BufferedReader(Reader in,int sz):创建了一个使用指定大小输入缓冲区的缓冲字符输入流。其中 sz指输入缓冲区的大小,如果sz<=0,则抛出IllegalArgumentException.
实例方法:
Public String readLine()throws IOException:读取一个文本行。
import java.io.*; public class BufferedIODemo2 { public static void main(String[] args){ FileReader fr=null; BufferedReader bw=null; try { fr=new FileReader("res/demo.txt"); bw=new BufferedReader(fr,255);
String str=null; while((str=bw.readLine())!=null){ System.out.println(str); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(bw!=null) try { bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } |
3 字符缓冲输出流BufferedWriter类
构造方法:
Public BufferedWriter(writer out):创建一个使用默认大小输出缓冲区的缓冲字符输出流。
Public BufferedWriter(Writer out,int sz):创建一个使用给定大小输出缓冲区的新缓冲字符输出流。其中 sz指输入缓冲区的大小,如果sz<=0,则抛出IllegalArgumentException.
实例方法:
Public void newLine()throw IOException:写入一个行分隔符,行分隔符字符串由系统属性line.separator定义,而不是单个新行(\n)符。
import java.io.*; public class BufferedIODemo { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub FileWriter fw=null; BufferedWriter bw=null; try { fw=new FileWriter("res/" + "demo.txt"); bw=new BufferedWriter(fw); bw.write("hell"); bw.newLine(); bw.write("java"); bw.newLine(); bw.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ if(bw!=null){ try { bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } |
4 装饰模式
缓冲字符流采用了装饰模式。
(1)抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
(2)具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
(3)装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。
(4)具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任。
Readr 和 Writer 为抽象构件,FileReader 和 FileWriter为实际操作类,BufferedReader和BufferedWriter为装饰类。
五 字节流
1 抽象基类InputStream、OutputStream
字节流可以操作任何数据
字符流使用的是字符数组;字节流使用的是字节数组
nputStream常用的方法:
read():从流中读取数据
available():返回流中可用的字节数
OutputStream常用的方法:
write(int b);将一个整数输出到流中
实例9:
FileInputStream和FileOutputStream的使用。
FileOutputStream fos = new FileOutputStream("a.txt"); fos.write("abcde");//直接将数据写入到了目的地。 fos.close();//只关闭资源。 FileInputStream fis = new FileInputStream("a.txt"); //fis.available();//获取关联的文件的字节数。
//如果文件体积不是很大,可以这样操作。 byte[] buf = new byte[fis.available()];//创建一个刚刚好的缓冲区。但是这有一个弊端,就是文件过大,大小超出jvm的内容空间时,会内存溢出。 fis.read(buf);
System.out.println(new String(buf)); |
2 转换器
OutputStreamWriter和InputStreamReader的构造—他们本身是字符流,又具有转换的作用,因此在构造的时候,需要传入字节流对象
public OutputStreamWriter(OutputStream out)
public OutputStreamWriter(OutputStream out, String charsetName)
public InputStreamReader(InputStream in)
public InputStreamReader(InputStream in, String charsetName)
实例10,转换流的使用。
操作文件的字符流FileReader和FileWriter是转换流的子类,因此从他们的继承关系就可以清楚的发现,不管是使用字节流还是字符流实际上最终都是以字节的形式操作输入和输出的。
注意:在使用FileReader操作文本数据时,该对象使用的是默认的编码表。如果要使用指定编码表时,必须使用转换流。
FileReader fr = new FileReader("a.txt");
//操作a.txt的中的数据使用的本系统默认的GBK
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
3 标准输入输出流
标准输入System.in
System.in作为字节输入流类InputStream的对象,实现标准的输入,使用其read()方法从键盘接收数据。
public int read() throws IOException
public int read(byte[] i) throws IOException
标准的输出System.out
System.out是打印流类PrintStream的对象,用来实现标准输出。print()和println()方法,支持任意的基本类型作为参数。
public void print(参数)
public void println(参数)