java IO流总结篇(一)
来源:互联网 发布:中国项目数据分析师 编辑:程序博客网 时间:2024/05/22 22:01
/***@author StormMaybin*Date 2016-07-28*/
生命不息,奋斗不止!
IO流是一个很重要的概念,不经常用难免会忘记,所以我们共同来复习一下这个庞大而且重要的东西,IO流总结会分为两篇,按照字节流和字符流展开!
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
IO流的分类
- 根据处理数据类型的不同分为:字符流和字节流
- 根据数据流向不同分为:输入流和输出流
字符流和字节流
- 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
- 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
输入流和输出流
对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。
IO流的基本概念就介绍到这,下来先来看看java中IO流的框架体系
初识IO框架,会有一种茫然失措的感觉,那么现在我们先从字符流最简单的操作——读写,开始看!
字符流
Reader
- Reader 是所有的输入字符流的父类,它是一个抽象类。
- CharReader、StringReader 是两种基本的介质流,它们分别将Char 数组、String中读取数据。PipedReader 是从与其它线程共用的管道中读取数据。
- BufferedReader 很明显就是一个装饰器,它和其子类负责装饰其它Reader 对象。
- FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰,会增加一个行号。
- InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader 可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。后面会有Reader 与InputStream 的对应关系。
Writer
- Writer 是所有的输出字符流的父类,它是一个抽象类。
- CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedWriter 是向与其它线程共用的管道中写入数据,
- BufferedWriter 是一个装饰器为Writer 提供缓冲功能。
- PrintWriter 和PrintStream 极其类似,功能和使用也非常相似。
- OutputStreamWriter 是OutputStream 到Writer 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类(具体可以研究一SourceCode)。功能和使用和OutputStream 极其类似,后面会有它们的对应图。
我们先来看看怎么创建一个文件,然后往里面写入数据
package com.stormma.writer;import java.io.*;public class FileWriterDemo{ public static void main(String[] args) { FileWriter fileWriter = null; //关联流和文件的时候,会抛出找不到文件异常,这个异常是IOException的子类,所以我们在这里try,catch一下 try { fileWriter = new FileWriter("writer.txt"); fileWriter.write("abcde"); } catch (IOException e) { e.printStackTrace(); } finally { if (fileWriter != null) { try { //关闭流之前会自动刷新 fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } }}
既然已经成功写入数据了,接下来开始读取文件的数据
package com.stormma.reader;import java.io.*;public class FileReaderDemo{ /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub FileReader fileReader = null; try { fileReader = new FileReader("writer.txt"); /*** * 单个字符读取 * int ch = 0; * while ((ch = fileReader.read()) != -1) * { * System.out.print((char)ch); * } */ char [] buf = new char [5]; int num = 0; num = fileReader.read(buf); System.out.println(buf); } catch (IOException e) { e.printStackTrace(); } finally { if (fileReader != null) { try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } } }}
很明显上面的代码效率太低,那么对应的缓冲区的出现很好的提高了流的操作效率!查阅源代码可以发现,BufferedReader装饰了Reader,从而提高了流的操作效率,从而演变出来的是java中的装饰设计模式,这种模式很好的降低了类与类的耦合性!
演示代码
package com.stormma.FileReaderWriter;import java.io.*;public class BufferedReaderDemo{ /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub FileReader fr = null; BufferedReader bufr = null; String lines = null; try { fr = new FileReader("buf.txt"); bufr = new BufferedReader(fr); while ((lines = bufr.readLine()) != null) { System.out.println(lines); } } catch (IOException e) { e.printStackTrace(); } finally { if(fr != null) { try { fr.close(); } catch(IOException e) { e.printStackTrace(); } } } }}
读取和写入是一样的,写入数据对应的类BufferedWriter可以直接写入一行!
我们仔细观察上面的代码,不难发现经过BufferedReader的装饰之后,读取数据可以一次读取一行,这样很好的提高了流的操作效率,但是readLine()方法是怎么实现的呢?我们可不可以自己定义一个BufferReader类来实现这些功能呢?答案是肯定的!
自定义BufferedReader
package com.stormma.FileReaderWriter;import java.io.*;/*** * 自定义BufferedReader * 实现readLine()方法 * @author StormMaybin * */public class MyBufferedReader{ private FileReader fr; /*** * BufferedReader初始化参数是流对象 * 所以这里的构造函数应该是带有流对象的构造函数 * @author StormMaybin * @param fr */ public MyBufferedReader(FileReader fr) { this.fr = fr; } public String myReadLine()throws IOException { /*** * BufferedReader的readLine()方法 * 内部是调用的FileRader中的read 方法 * 并且用数组来存储读取的字符,这里为了方便, * 定义一个StringBuilder容器来存储读到的 * 字符 * */ StringBuilder sb = new StringBuilder(); int ch = 0; //因为这里的read方法有可能会抛出异常 //所以这个函数申明可抛出异常 while ((ch = fr.read()) != -1) { if (ch == '\r') { continue; } else if (ch == '\n') { return sb.toString(); } else { sb.append((char)ch ); } } //避免丢失最后一行 if (sb.length() != 0) { return sb.toString(); } return null; } /*** * myClose方法 * 实现关闭流功能 * @throws IOException */ public void myClose()throws IOException { fr.close(); }}
我们新建一个类使用自定义的readLine()方法
/*** * 演示类 * @author StormMaybin * */class MyBufferedReaderDemo { //这里为了方便,没有trycatch,直接抛出去了! public static void main (String [] args)throws IOException { FileReader fr = new FileReader("buf.txt"); MyBufferedReader mbufr = new MyBufferedReader(fr); String lines = null; while ((lines = mbufr.myReadLine()) != null) { System.out.println(lines); } mbufr.myClose(); }}
演示结果和上面的结果是一致的
9 2
- java IO流总结篇(一)
- java Io总结一(输入输出流)
- Java IO流学习总结(一)
- java中的IO流总结(一)
- Java IO 总结(一)
- IO流总结(一)
- JAVA IO流总结(一)——字符流
- java学习笔记之IO流总结(一)
- java中的IO操作总结(一)
- java中的IO操作总结(一)
- java中的IO操作总结(一)
- java中的IO操作总结(一)
- java中的IO操作总结(一)
- Java中的IO操作总结(一)
- java中的IO操作总结(一)
- java中的IO操作总结(一)
- java IO流总结篇(二)
- Java总结(9) IO(一)
- Android之项目中调用已有.so库
- jsf架构
- 用CnetOs7编译hadoop2.7.2
- Java 读写Properties配置文件
- POJ 3172 Scales(dfs搜索)
- java IO流总结篇(一)
- java容器简介
- 栈的基本操作
- listview的多条目样式适配
- 2016 Multi-University Training Contest 4 - 1011 Where Amazing Happens(水水水)
- 面试题59:对称的二叉树
- GridView的下拉刷新上拉加载
- C++ std::sort和 std::stable_sort
- Y2K Accounting Bug