IO流介绍
首先应该明确,流是一个抽象的概念,描述了数据的无结构化传递方式。
IO流,顾名思义,就是以流的方式进行输入输出;也就是说,在IO流中,传输的字符序列或字节序列是无结构化的。
IO流的分类
按照数据的传递方向:被分为输入流和输出流。
按照传输数据的类型:被分为字节流和字符流。
字符流
字符流:字符流就是Unicode字符集以流的方式传递。注意:在java中char类型占用两个字节。所以char类型也能够保存汉字,也就是属于Unicode字符集中的任何字符都可用char类型传递。
字符流的分类介绍
Reader(字符输入流):在JDK1.6中,该抽象类为字符流输入流的超类。从外部读入系统。
Writer(字符输出流):在JDK1.6中,该抽象类为字符流输出流的超类。从系统向外输出
直接子类
BufferedReader(缓冲输入流):该类为Reader类的直接子类,作用是:缓冲字符输入流中的字符,从而实现单个字符、字符数组、字符行的高效读取。
BufferedWriter(缓冲输出流):该类为Writer类的直接子类,作用是:缓冲字符输出流中的字符,从而实现单个字符、字符数组、字符行的高效输出。
InputStreamReader(输入转换流):该类为Reader类的直接子类,作用是:把字节输入流中的字节转换为字符输入流,必要时也可以指定编码。
OutputStreamWriter(输出转换流):给类为Writer类的直接子类,作用是:把字节输出流中的字节转换为字符输出流,并在必要时指定编码。
间接子类
FileReader(文件读取流):该类是InputStreamReader的直接子类,作用:是用来读取字符文件的便捷类。
FileWriter(文件输出流):该类是OutputStreamWriter的直接子类,作用:把字符输出到文件的便捷类。
字节流
字节流:字节流就是二进制字节码以流的方式传递,这种方式可以传递所有的信息。
字符流分类介绍
InputStream(字节输入流):在JDK1.6中,该类是一个抽象类,为所有字节输入流的超类。从外部读入系统
OutputStream(字节输出流):在JDK1.6中,该类是一个抽象类,为所有字节输出流的超类,从系统输出到外部。
直接子类
FileInputStream(文件读取流):该类是InputStream的直接子类,是以字节流的方式读取文件的便捷类。但需要注意的是:读取的文件是否被允许读,则取决于操作平台
FileOutputStream(文件输出流):该类是OutputStream的直接子类,以字节的形式向文件中写入内容,但需要注意的是:在某些操作平台不允许多个OutputStream对象对同一文件进行操作。
间接子类
BufferedOutputStream(缓冲字节输出流):该类是FilterOutputStream类的直接子类,作用是:创建缓冲输出流,将字节写入底层输出流。
BufferedInputStream(缓冲字节输入流):该类是FilterInputStream类的直接子类,作用:缓冲输入,以及支持mark() 和reset()方法的能力。mark() :对当前流做标记,reset():定位当前流至最后一次标记处,以实线该标记之后内容的重复读入。
装饰设计模式
通常描述为,为了增强某些类的功能,创建一个新类,在新类中对原有类的功能和逻辑进行增强;在使用时被增强类的对象作为增强类的构造参数。
前提:增强类和被增强类属于同一体系
优点:对原有的类进行增强,并降低类之间的耦合度。
【注】在IO流中,BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream类就是增强类,实现了对Reader、Writer、InputStream、OutputStream等类以及子类的功能的增强,所以,在JDK API中,可以明显看到,BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream等类的构造方法参数为Reader、Writer、InputStream、OutputStream类型,即多态,而多态的优点就是:把运行阶段的错误提前到了编译阶段,并提高了代码的扩展性和复用性。
read():这是一个阻塞方法,一旦调用就会等待输出。所以在线程中,一旦有线程进行IO操作,那么该线程就会进入阻塞。
IO流使用部分示例
键盘输出:
public static void main(String[] args){
OutputStream out = system.out; //字节输出流
OutputStreamWriter oWriter = new OutputStreamWriter(out); //转换流
BufferedWriter bWriter = new BufferedWriter(oWriter); //增强字符流
bWriter.write("沉舟侧畔千帆过,病树前头万木春");
bWriter.newLine(); //换行
bWriter.flush();
bWriter.close();
}
键盘录入:
public static void main(String[] args){
InputStream in = system.in;
InputStreamReader iReader = new InputStreamReader(in);
BufferedReader bReader = new BufferedReader(iReader);
while(true){
String s="";
s=bReader.readLine(); //读取一行
if(s.equals("bye")){ //当读取内容为'bye'时代表输入结束
break;
}
System.out.println(s);
}
}
使用字节流的缓冲区实现文件拷贝:
import java.io.*;
class FileCopyDemo{
public static void main(String[] args) throws IOException{
long start = system.currentTimeMills();//当前系统时间
copy("D://apache-tomcat-7.0.40.zip","ss.zip");
long end = system.currentTimeMills();
System.out.println(end-start);
}
public static void copy(String oldName,String newName){
FileInputStream fInputStream = new FileInputStream(oldName);
BufferedInputSteam bInputStream = new BufferedInputStream(fInputStream);
FileOutputStream fOutputStream = new FileOnputStream(newName);
BufferedOutputStream bOutputStream = new BufferedOutputStream(fOutputStream);
byte[] buf= new Byte[1024*4];
int leng=0;
while((leng=bInputStream.read(buf)) != -1){ //读取buf数组大小的字节至该数组中,但要注意的是,并不是数组的大小越大越合适,而是在适当的范围内
bOutputStream.write(buf,0,leng);
bOutputStream.flush();
}
bInputStream.close();
bOutputStrem.close();
}
}
read()和write()方法的说明:
read()方法的返回值是读入的字节数大小,如没有内容读入,则返回-1;并且需要注意的是,读入的内容可以是单个字节,字节数组。详细参加JDK说明文档。
write()方法没有返回值,会将参数中的内容写入,详细参加JDK说明文档。