1、 流的概念
流(Stream)的概念代表的是程序中数据的流通,数据流是一串连续不断的数据的集合。在Java程序中,对于数据的输入/输出操作是以流(Stream)的方式进行的。可以把流分为输入流和输出流两种。程序从输入流读取数据,向输出流写入数据。在java程序中,从输入流读取数据(读到内存中),而从输出流输出数据(从内存存储到文件或显示到屏幕上),参见图
如果数据流中最小的数据单元是字节,那么称这种流为字节流;如果数据流中最小的数据单元是字符,那么称这种流为字符流。在I/O类库中,java.io.InputStream和java.io.OutputStream分别表示字节输入流和字节输出流,java.io.Reader和java.io.Writer分别表示字符输入流和字符输出流。
Java中的流可以按如下方式分类:
●按流的方向不同分为:输入流、输出流
●按处理数据的单位不同分为:字节流、字符流
●按功能不同分为:节点流、处理流
Java语言中,控制数据流的类都放在java.io包中,java.io包中有两大继承体系。以byte处理为主的Stream类,他们的命名方式是XXXStream;以字符处理为主的Reader / Writer类,他们的命名方式XXXReader或XXXWriter。InputStream、OutputStream、Reader、Writer这四个类,是这两大继承体系的父类,如表所示
抽象基类
高级流(缓冲流)
低级流(节点流).
字节流INPUTSTREAM
FILELNPUTSTREAM
BUFFEREDLNPUTSTREAM
BUFFEREDOUTPUTSTREAM
FILEOUTPUTSTREAM
OUTPUTSTREAM
字符流 READER
BUFFEREDREADER
FILEREADER
BUFFEREDWRITER
FILEWRITER
WRITER
(PRINTWRITER)
2、 InputStream字节输入流的层次结构图与常用方法
(1)层次结构
在java.io包中,java.io.InputStream表示字节输入流,java.io.OutputStream表示字节输出流,它们都是抽象类,不能被实例化。所有字节输入流都是InputStream类的直接或者间接子类。输入流的类层次结构如下图所示。
(2)常用方法
InputStream是表示输入字节流的所有类的超类,InputStream类常用的方法如表所示。
方法 | 含义 |
int read() | 一次读取一个byte的数据,并以int类型把数据返回来,如果没有数据可以读了,会返回”-1” |
int read(byte[] buffer) | 把所读取到的数据放在这个byte数组中,返回一个int型的数据,这个int型数据存储了返回的真正读取到的数据byte数 |
int read(byte[] buffer,int offset,int length) | 读取length个字节,并存储到一个字节数组buffer中,并从offset位置开始返回实际读取的字节数 |
void close() | 关闭此输入流并释放与该流关联的所有系统资源 |
3、 OutputStream字节输出流的层次结构图与常用方法
1. 层次结构
所有字节输出流都是OutputStream类的直接或者间接子类,输出流的类层次结构如图所示。
2. 常用方法
OutputStream是表示输出字节流的所有类的超类,OutputStream类常用的方法如表所示
方法 | 含义 |
void write(byte[] buffer) | 将要输出的数组先放在一个byte数组中,然后用这个方法一次把一组数据输出出去 |
void write(byte[] buffer,int off,int len) | 将指定字节数组中从偏移量off 开始的 len 个字节写入此输出流 |
abstract void write(int b) | 将指定的字节写入此输出流 |
void close() | 关闭此输出流并释放与此流有关的所有系统资源 |
void flush() | 刷新此输出流并强制输出所有缓冲的输出字节 |
4、 字符流应用
注意:存文件时要用utf-8编码,否则与我们的工作区编码方式 不匹配,出现乱码
【例】读字符文件
public class Test{@Testpublic void test07() throws IOException {//文本文件的编码方式改为utf-8// BufferedReader(Reader in) Reader我们选的是FileReader--->FileReader(File// file)File path = new File("d:" + File.separator + "java" + File.separator + "io");File file = new File(path, "test01.txt");FileReader fr = new FileReader(file);// 理解为是一个工具类,他专门用来读文本文件内容BufferedReader br = new BufferedReader(fr);while(true) {String str = br.readLine();// 一次读取一行文本if (str != null) {System.out.println(str);} else {break;}}}
}
【例】写字符流文件
public class Test{@Testpublic void test08() throws IOException {//确认文件是utf-8编码File path = new File("d:" + File.separator + "java" + File.separator + "io");File file = new File(path, "test01.txt");FileWriter fileWriter=null;//第一个参数是为是否appendBufferedWriter bw=null;try {fileWriter = new FileWriter(file,true);//第二个参数是表示是否向文件中追加内容bw=new BufferedWriter(fileWriter);bw.write("问:没声音吗");//写文本bw.newLine();//换行//bw.flush();//刷新后,文本写入文件} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{ //记着关闭流//如果调用了关闭流的方法,就不用手动调bw.flush()bw.close();fileWriter.close();}}
}
【例】文本文件拷贝(字符流)
public class Test{@Testpublic void test09() throws IOException{//从d:/java/io/test01.txt读//每读到一行,向d:/java/io/test02.txt写入//step1 初始化输入输出流FileReader fr=null;BufferedReader br=null;FileWriter fw=null;BufferedWriter bw=null;try {System.out.println("开始初始化输入输出流");//初始化输入流File path = new File("d:" + File.separator + "java" + File.separator + "io");File inputFile = new File(path, "test01.txt");fr=new FileReader(inputFile);br=new BufferedReader(fr);//初始化输出流File outputFile = new File("d:" + File.separator + "java" + File.separator + "io"+File.separator +"test02.txt");fw=new FileWriter(outputFile,true);bw=new BufferedWriter(fw);//step2 死循环从输入流(也就是text01.txt)一行一行读while(true){//一次读取一行String content=br.readLine();if(content!=null){//如果读到的内容不为nullSystem.out.println("读到了一行,开始写入");bw.write(content);bw.newLine();}else{System.out.println("拷贝完成");break;}}} catch (Exception e) {// 打印异常e.printStackTrace();}finally{//关闭流bw.close();fw.close();br.close();fr.close();}}
}
4、 字节流应用
【例】文本文件拷贝(字节流
//字节流拷贝
@Testpublic void test07(){//FileInputStream BufferedInputStream//FileOutputStream BufferedOutputStreamFile file=new File("E:" + File.separator + "java6" + File.separator + "filestudy", "01.png");FileInputStream in=null;BufferedInputStream bis=null;File file2=new File("E:" + File.separator + "java6" + File.separator + "filestudy", "10.png");FileOutputStream out=null;BufferedOutputStream bos=null;try {in=new FileInputStream(file);bis=new BufferedInputStream(in);out = new FileOutputStream(file2);bos=new BufferedOutputStream(out);//读取到的字节的长度int b;//bis.read() 每次读取到的字节数,注意此处给b重新赋值 ,否则死循环while((b=bis.read())!=-1){//把b长度的字节写入到bos里bos.write(b);}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {bos.close();out.close();bis.close();in.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}