概述

流的概念和作用

流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

IO流分类

按流的方向分类:
   
输入流:数据流向是数据源到程序(以InputStream、Reader结尾的流)
    输出流:数据流向是程序到目的地(以OutPutStream、Writer结尾的流)
按处理的数据单元分类:
    字节流
:以字节为单位获取数据,命名上以Stream结尾的流一般是字节流,如FileInputStream、FileOutputStream
    字符流:以字符为单位获取数据,命名上以Reader/Writer结尾的流一般是字符流,如FileReader、FileWriter
按处理对象不同分类:
   
节点流:可以直接从数据源或目的地读写数据,如FileInputStream、FileReader、DataInputStream等
    处理流(包装流):不直接连接到数据源或目的地,是”处理流的流”。通过对其他流的处理提高程序的性能,
                    如BufferedInputStream、BufferedReader等

java流类图结构

学习IO流注意把握四大抽象基类:InputStream、OutputStream、Reader、Writer

InputStream

所有的输入字节流的父类,它是一个抽象类。

ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。PipedInputStream 是从与其它线程共用的管道中读取数据

ObjectInputStream 和所有FilterInputStream的子类都是装饰流(装饰器模式的主角)。意思是FileInputStream类可以通过一个String路径名创建一个对象,FileInputStream(String name)。而DataInputStream必须装饰一个类才能返回一个对象,DataInputStream(InputStream in)

OutputStream

所有的输出字节流的父类,它是一个抽象类。

ByteArrayOutputStream、FileOutputStream是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据,

ObjectOutputStream 和所有FilterOutputStream的子类都是装饰流。

Reader

所有的输入字符流的父类,它是一个抽象类。

CharReader、StringReader是两种基本的介质流,它们分别将Char 数组、String中读取数据。PipedReader 是从与其它线程共用的管道中读取数据。

BufferedReader 很明显就是一个装饰器,它和其子类负责装饰其它Reader 对象。

FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰,会增加一个行号

InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。

Writer

所有的输出字符流的父类,它是一个抽象类。

CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。

PipedWriter 是向与其它线程共用的管道中写入数据,

BufferedWriter 是一个装饰器为Writer 提供缓冲功能。

PrintWriter 和PrintStream 极其类似,功能和使用也非常相似。

OutputStreamWriter 是OutputStream 到Writer 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类(具体可以研究一SourceCode)。功能和使用和OutputStream 极其类似,后面会有它们的对应图。


常用类

FileInputStream/FileOutputStream
节点流:以字节为单位直接操作“文件”
FileReader/FileWriter
节点流:以字符为单位直接操作“文本文件”(注意:只能读写文本文件)

BufferedInputStream/BufferedOutputStream
处理流:将InputStream/OutputStream对象进行包装,增加缓存功能,提高读写效率
BufferedReader/BufferedWriter
处理流:将Reader/Writer对象进行包装,增加缓存功能,提高读写效率
InputStreamReader/OutputStreamWriter
处理流:将字节流对象转化成字符流对象(转换流

DataInputStream/DataOutputStream
处理流:以字节为单位直接操作“基本数据类型与字符串类型”
ObjectInputStream/ObjectOutputStream
处理流:以字节为单位直接操作“对象”
PrintStream
处理流:将OutputStream进行包装,可以方便地输出字符,更加灵活

操作步骤:

  • 1.创建源
  • 2.选择流
  • 3.操作(读取或写出)
  • 4.关闭流

Java IO流对象

1.字节输入流InputStream

常用方法:

read() 读取单个字节 返回值为读取内容 返回类型int 结束返回-1
read(byte[])  读取一段byte数组长度的字节 返回值为读取长度   返回类型int  结束返回-1

demo  单字节读取

package IO;
/*** 字节输入流* 单字节读取*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;public class InputStreamTest {public static void main(String[] args) {       //1.创建源File src = new File("d:/1.txt");  //内容是abc def//2.选择流InputStream is = null;try {is = new FileInputStream(src);StringBuilder sb = new StringBuilder(); //读取的字节存到sb中//3.操作(读取)int temp = 0;while((temp=is.read())!=-1) {sb.append((char)(temp));}System.out.println(sb);  //abc def} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {//4.关闭流try {if(is != null) {is.close();                 } } catch (IOException e) {e.printStackTrace();}}}
}
/*
第一个异常是在is = new FileInputStream(src)创建流时可能出现FileNotFoundException
第二个异常是在temp=is.read()读取时可能无法读取或者流已经关闭等原因出现IOException
第三个异常是关闭流时可能出现IOException(注意之前可能会发生流没创建成功就报异常,关流
也就没有意义  所以判断下流不为null)
*/

demo 一段一段的读(其他部分都和一个字节一个字节读取相同)

//3.操作(读取)byte[] buf = new byte[1024]; //1024个字节即1kbint len = -1;  //接收长度while((len=is.read(buf))!=-1) {//字节数组到字符串(解码)String newstr = new String(buf,0,len);System.out.println(newstr);  //abc def}

2.字节输出流OutputStream

常用方法:

write() 写出单个字节 无返回值
write(byte[],int off,int len)  从off开始写出len长度字节

demo  字节数组  也可以一个字节一个字节读  加个循环即可

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;/*** 字节输入流* 还是创建源 选择流 操作  关流* @author chen**/
public class OutputStreamTest {public static void main(String[] args) {File dest = new File("d:/2.txt");  //不存在会自动创建OutputStream os = null;try {os = new FileOutputStream(dest);  //默认是覆盖模式//OutputStream os = new FileOutputStream(dest,true);追加模式String str = "hello java"; //要写的数据//字符串转字节数组(编码)byte[] buf = str.getBytes();os.write(buf, 0, buf.length);os.flush();  //写出时注意刷新} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {try {if(os!=null) {os.close();           }} catch (IOException e) {e.printStackTrace();}}}
}

复制文件

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;/*** 字节流复制文件(mp3)* @author chen**/
public class CopyFileStream {public static void main(String[] args) {File src = new File("d:/1.mp3");File dest = new File("e:/2.mp3");InputStream is = null;OutputStream os = null;try {is = new FileInputStream(src);os = new FileOutputStream(dest);byte[] buf = new byte[1024];int len = -1;while((len=is.read(buf))!=-1) {os.write(buf,0,len);os.flush();  //写一次刷一次}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {try {if(os!=null) {os.close(); }if(is!=null) {is.close();                 }} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
}

字节流可以处理如文本、图片、音频、视频等所有格式的文件,但是在处理涉及中文的文本时由于编码格式的问题可能会出现乱码问题,所以处理纯文本时使用字符流。


3.字符输入流Reader

Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致

常用方法

read() 读取单个字符 返回值为读取内容 返回类型int 结束返回-1
read(char[])  读取一段char数组长度的字符 返回值为读取长度  返回类型int  结束返回-1
read(char[] cbuf, int off, int len) 

demo  字符数组   也可以 单个字符

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;/*** 字符输入流* @author chen**/
public class FileReaderTest {public static void main(String[] args) {File src = new File("d:/1.txt");FileReader fr = null;try {fr = new FileReader(src);char[] buf = new char[1024];int len = -1;while((len=fr.read(buf))!=-1) {String str = new String(buf,0,len);System.out.println(str);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally {try {if(fr!=null) {fr.close();                   }} catch (IOException e) {e.printStackTrace();}}}
}

4.字符输出流Writer

常用方法

write(int c) 写出单个字符 无返回值
write(byte[])  写出字符数组  无返回值
write(byte[],int off,int len)
//与字节输出流相比增加了写字符串方法
write(String str)  写一个字符串
write(String str, int off, int len) 

demo

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;/*** 字符输出流 * @author chen**/
public class FileWriterTest {public static void main(String[] args) {File dest = new File("d:/3.txt");FileWriter fw = null;try {fw = new FileWriter(dest);String str = "你好呀  java";char[] buf = str.toCharArray();fw.write(buf);fw.flush();} catch (IOException e) {e.printStackTrace();}finally {try {if(fw!= null) {fw.close();                 }} catch (IOException e) {e.printStackTrace();}}}
}

常用处理流

字节缓冲流BufferedInputStream/BufferedOutputStream

与字节流方法一样,只不过增加了缓冲区,提高了效率 注意关闭流时关闭bis/bos即可

demo  复制文件

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class ByteBufferedCopy {public static void main(String[] args) {File src = new File("d:/1.mp3");File dest = new File("e:/3.mp3");BufferedInputStream bis = null;BufferedOutputStream bos = null;try {bis = new BufferedInputStream(new FileInputStream(src));bos = new BufferedOutputStream(new FileOutputStream(dest));byte[] buf = new byte[1024];int len = -1;while((len = bis.read(buf)) != -1) {bos.write(buf);bos.flush();}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {try {if(bos != null) {bos.close();}} catch (IOException e) {e.printStackTrace();}try {if(bis != null) {bis.close();}} catch (IOException e) {e.printStackTrace();}}}
}

字符缓冲流BufferedReader/BufferedWriter

与字符流基本形同,只不过增加了readLine读一行的方法和newLine换行方法,注意关闭流时关闭br/bs即可

//BufferedReader中:
read()  读取单个字符  返回读取内容int  结束返回-1
read(char[] cbuf, int off, int len)
//增加了readline()方法  可以一次读取一行
readLine()   读取一行数据   返回数据  返回类型StringBufferedWriter中
write(int c)
write(char[] cbuf, int off, int len)
write(String s)
write(String s, int off, int len)
//增加了换行
newLine()

demo  复制文件

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;public class CharBufferCopy {public static void main(String[] args) {File src = new File("d:/1.txt");File dest = new File("d:/4.txt");BufferedReader br = null;BufferedWriter bw = null;try {br = new BufferedReader(new FileReader(src));bw = new BufferedWriter(new FileWriter(dest));String str = null;while((str = br.readLine()) != null) {bw.write(str);bw.newLine();bw.flush();}} catch (IOException e) {e.printStackTrace();}finally {try {bw.close();} catch (IOException e) {e.printStackTrace();}try {br.close();} catch (IOException e) {e.printStackTrace();}}}
}

字节流转字符流InputStreamReader/OutputStreamWriter

作用:
(1)将字节流转换为字符流方便操作(前提是字节流是纯文本的情况)
(2)处理过程中可以指定编码格式(创建时可以指定字符集InputStreamReader(InputStream in, Charset cs) )

demo:键盘录入输出到控制台

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;/*** 转换流  * InputStreamReader* OutputStreamWriter* 键盘录入直接输出到控制台* @author chen**/
public class InputStreamReaderTest {public static void main(String[] args) {//操作字节输入输出流System.in和System.outInputStreamReader isr = new InputStreamReader(System.in);  //键盘录入字节流 转换为字符流OutputStreamWriter osr = new OutputStreamWriter(System.out);  //输出BufferedReader br = new BufferedReader(isr);BufferedWriter bw = new BufferedWriter(osr);//循环获取键盘输入(over结束)String str = null;try {while(!(str=br.readLine()).equals("over")) {bw.write(str);bw.newLine();bw.flush();}} catch (IOException e) {e.printStackTrace();}finally {if (br != null) {try {br.close();} catch (IOException e) {e.printStackTrace();}}if (bw != null) {try {bw.close();} catch (IOException e) {e.printStackTrace();}}}}
}

其他处理流

数据流DataInputStream/DataOutputStream

数据流将“基本数据类型与字符串类型”作为数据源,实现不仅可以读写数据,还可以同时把数据的类型进行读写

注意:要先写出后读取并且读取的顺序与写出的顺序一致

demo

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class DataStreamTest {public static void main(String[] args) {File src = new File("d:/data.txt");  File dest = new File("d:/data.txt"); DataInputStream dis = null;DataOutputStream dos = null;try {dis = new DataInputStream(new BufferedInputStream(new FileInputStream(src)));dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));//将以下数据写入到文件中dos.writeChar('a'); dos.writeInt(10);dos.writeUTF("陈陈陈");  //utf8编码格式写汉字dos.flush();//直接读取数据,读取的顺序与写入的顺序一致。否则不能读取char c = dis.readChar();int i = dis.readInt();String str = dis.readUTF();System.out.println(c);System.out.println(i);System.out.println(str);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {try {if(dos!=null) {dos.close();                      }} catch (IOException e) {e.printStackTrace();}try {if(dis!=null) {dis.close();                        }} catch (IOException e) {e.printStackTrace();}}}
}

对象流(ObjectInputStream/ObjectOutputStream)

除了像数据流那样读写基本数据类型和字符串外还可以读取写出任意对象,包含自定义对象

序列化:   把Java对象转换为字节序列
反序列化: 把字节序列恢复为Java对象的过程
对象序列化的作用:
(1)持久化: 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中,
            比如:休眠的实现。以后服务器session管理,hibernate将对象持久化实现
(2)网络通信:在网络上传送对象的字节序列
            比如:服务器之间的数据通信、对象传递
            
ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

注意:
要先写出后读取并且读取的顺序与写出的顺序一致
只有实现了Serializable接口的对象才能被序列化。 Serializable接口是一个空接口,只起到标记作用

demo

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;public class ObjectStreamTest {public static void main(String[] args) {File src = new File("d:/9.txt");  File dest = new File("d:/9.txt"); ObjectInputStream ois = null;ObjectOutputStream oos = null;try {ois = new ObjectInputStream(new FileInputStream(src));oos = new ObjectOutputStream(new FileOutputStream(dest));//序列化oos.writeObject("chencc");oos.writeObject(new Person("chen",20));oos.flush();//反序列化Object strobj = ois.readObject();Object perobj = ois.readObject();if(strobj instanceof String) {System.out.println((String)strobj);               }if(perobj instanceof Person) {Person p = (Person)perobj;System.out.println(p.getName()+"  "+p.getAge());              }} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}finally {try {if(oos!=null) {oos.close();                        }} catch (IOException e) {e.printStackTrace();}try {if(ois!=null) {ois.close();                        }} catch (IOException e) {e.printStackTrace();}}}
}//自定义对象 要想序列化必须实现Serializable接口
class Person implements Serializable{//产生一个随机固定的idprivate static final long serialVersionUID = 1L;private String name;private transient int age;  被transient修饰的属性不参与序列化public Person(String name,int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}

打印流PrintStream

可以把内容打印到文件或者输出流中,增强了输出流的功能而已

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;public class PrintStreamTest {public static void main(String[] args) {//System.out就是打印流PrintStream ps = System.out;ps.println("java");   //和System.out.println("java") 一样ps.println("你好");//也可以打印到文件,指定编码try {ps = new PrintStream("d:/haha.txt","utf-8");ps.println("java");ps.println("你好");} catch (FileNotFoundException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();}finally {if(ps!=null) {ps.close();              }}//可以打印到输出流try {ps = new PrintStream(new BufferedOutputStream(new FileOutputStream("d:/heihei.txt")),true);//true表示自动flushps.println("java");ps.println("你好");} catch (FileNotFoundException e) {e.printStackTrace();}finally {if(ps!=null) {ps.close();               }}//重定向输出端(也可以重定向输入端)System.setOut(ps); //重定向到上面的文件heihei.txt了System.out.println("abc");}
}

CommonsIO

Apache-commons工具包中提供了IOUtils/FileUtils,封装了大量的IO流操作,可以让我们非常方便的对文件和目录进行操作

下载地址:http://commons.apache.org/proper/commons-io/      用的时候直接查API即可

demo

import java.io.File;import org.apache.commons.io.FileUtils;public class TestCommons01 {public static void main(String[] args) {//文件大小//自己写的话还要用递归 这个已经封装好了long len = FileUtils.sizeOf(new File("d:/1.txt"));System.out.println(len);  }
}

7.java IO流相关推荐

  1. Java IO流学习总结四:缓冲流-BufferedReader、BufferedWriter

    Java IO流学习总结四:缓冲流-BufferedReader.BufferedWriter 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/det ...

  2. Java IO流学习总结三:缓冲流-BufferedInputStream、BufferedOutputStream

    Java IO流学习总结三:缓冲流-BufferedInputStream.BufferedOutputStream 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/ ...

  3. Java IO流思维导图

    Java IO流

  4. Java读取文件流用什么对象_使用Java IO流实现对文本文件的读写过程中,通常需要处理下列( )异常。_学小易找答案...

    [论述题]请根据第一次平时作业的选题,结合第二次课内容,自拟一个论文提纲. [单选题]在 switch ( expression )语句中, expression 的数据类型不能是 ( ) [单选题] ...

  5. java io流大全_Java IO流系统整理

    Java IO流的分类 Java中的流,可以从不同的角度进行分类. 按流向分类: 输入流: 程序可以从中读取数据的流. 输出流: 程序能向其中写入数据的流. 按数据传输单位分类: 字节流:以字节(8位 ...

  6. Java IO流学习总结八:Commons IO 2.5-IOUtils

    Java IO流学习总结八:Commons IO 2.5-IOUtils 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/550519 ...

  7. Java IO流学习总结七:Commons IO 2.5-FileUtils

    Java IO流学习总结七:Commons IO 2.5-FileUtils 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/5497 ...

  8. Java IO流学习总结六:ByteArrayInputStream、ByteArrayOutputStream

    Java IO流学习总结六:ByteArrayInputStream.ByteArrayOutputStream 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/ar ...

  9. Java IO流学习总结二:File

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/54581478 本文出自[赵彦军的博客] Java IO流学习总结一:输入输出流 J ...

  10. java io流(字符流) 文件打开、读取文件、关闭文件

    java io流(字符流) 文件打开 读取文件 关闭文件 //打开文件 //读取文件内容 //关闭文件 import java.io.*;public class Index{public stati ...

最新文章

  1. 用户 Outlook 2007 附件突然不能预览,在国外网站找了解决方案。
  2. Shell数组操作(添加、删除元素、清空、遍历)
  3. /usr/include/sys/stat.h文件属性
  4. Oracle数据库文件路径变更
  5. 存储过程中用到的年,月,周的函数
  6. Web应用与HTTP协议
  7. 利用jmeter做一个简单的性能测试并进行参数化设置
  8. Linux驱动开发|音频驱动
  9. 个人风景网站模板HTML+CSS+JS(源码)
  10. 图灵大会圆满落幕,码隆科技与全球最强大脑同台
  11. 复变|第一章 复数与复变函数 复数
  12. Netlogon漏洞复现
  13. mysql数据库重启、登录mysql数据库、通过命令执行mysql的sql脚本等命令
  14. 机器博弈:非零和博弈下的叶值表剪枝
  15. Word Vector的综述
  16. 圆填充( CIRCLE PACKING)算法圆堆图圆形空间填充算法可视化
  17. 数据结构与算法题目及C++解答
  18. 2.1.4 运算放大器的等效模型、理想运算放大器的特性
  19. Java 8 辣么大(lambda)表达式不慌之-----(一)Function
  20. H5页面实现下载文件兼容移动端

热门文章

  1. PAT1150 Travelling Salesman Problem
  2. 冷静 仔细 认真 分析
  3. 第二讲:云分类及服务模式
  4. php一元二次方程求根,JavaScript_在线一元二次方程计算器实例(方程计算器在线计算),复制代码 代码如下:htmll - phpStudy...
  5. nginx 监听多个端口 80和81
  6. Set接口介绍、HashSet源码简要分析
  7. Meebo 和 GMail + Talk 等 WebIM 的实现方式
  8. #一份怀念# 致亲爱的旺旺狗狗
  9. windows如何查找自己的office秘钥?
  10. 在中国,考不上高中的孩子去哪儿了