您的位置:首页 > 编程语言 > Java开发

java IO流总结篇(一)

2016-07-28 19:41 330 查看
/**
*@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();
}
}


演示结果和上面的结果是一致的

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java io流 字符流 数据