java IO流总结篇(一)
java,io流,字符流,数据2016-07-28
/**
*@author StormMaybin
*Date 2016-07-28
*/
生命不息,奋斗不止!
IO流是一个很重要的概念,不经常用难免会忘记,所以我们共同来复习一下这个庞大而且重要的东西,IO流总结会分为两篇,按照字节流和字符流展开!
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。
IO流的基本概念就介绍到这,下来先来看看java中IO流的框架体系
初识IO框架,会有一种茫然失措的感觉,那么现在我们先从字符流最简单的操作——读写,开始看!
Reader
Writer
我们先来看看怎么创建一个文件,然后往里面写入数据
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类来实现这些功能呢?答案是肯定的!
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();
}
}
演示结果和上面的结果是一致的