一、Java I/O类结构以及流的基本概念

在阅读Java I/O的实例之前我们必须清楚一些概念,我们先看看Java I/O的类结构图:

这里写图片描述

Java I/O主要以流的形式进行读写数据。

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

根据处理数据的数据类型的不同可以分为:字符流和字节流。

字符流和字节流的主要区别:

1.字节流读取的时候,读到一个字节就返回一个字节; 字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8码表中是3个字节)时。先去查指定的编码表,将查到的字符返回。

2.字节流可以处理所有类型数据,如:图片,MP3,AVI视频文件,而字符流只能处理字符数据。只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流。

3.实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件。

下面我们以文件操作作为实例进一步了解。

二、字符流实例

之前提到过“只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流”。因此本字符流操作实例是操作txt文件。对其进行读写操作。

2.1、一些概念

此前,我们需要了解一些概念。

Java采用16位的Unicode来表示字符串和字符的。在写入字符流时我们都可以指定写入的字符串的编码。

这里博主贴出字符流类图结构,方便猿友阅读:

这里写图片描述

在文件操作的时候我们主要使用到FileReader和FileWriter或BufferedReader和BufferedWriter。

从类结构图来看:

FileReader是InputStreamReader的子类,而InputStreamReader是Reader的子类;

FileWriter是OutputStreamWriter的子类,而OutputStreamWriter则是Writer的子类。

2.2、FileReader和BufferedReader的使用

FileReader的常用构造包括以下两种:

(1)FileReader(String fileName):根据文件名创建FileReader对象。

(2)FileReader(File file):根据File对象创建FileReader对象。

FileReader的常用方法包括以下几种:

(1)int read():读取单个字符。返回字符的整数值,如果已经到达文件尾,则返回-1.

(2)int read(char[] cbuf):将字符读入cbuf字符数组。返回读取到的字符数,如果已经到达文件尾,则返回-1.

(3)int read(char[] cbuf,int off,int len):将读取到的字符存放到cbuf字符数组从off标识的偏移位置开始处,最多读取len个字符。

BufferedReader有以下两种构造方法:

(1)BufferedReader(Reader in):根据in代表的Reader对象创建BufferReader实例,缓冲区大小采用默认值。

(2)BufferedReader(Reader in,int sz):根据in代表的Reader对象创建BufferedReader实例,缓冲区大小采用指定sz值。

BufferedReader的常用方法包括以下几种:

(1)int read():返回字符的整数值,如果已经到达文件尾,则返回-1.

(2)int read(char[], int, int):将读取到的字符存放到cbuf字符数组从off标识的偏移位置开始处,最多读取len个字符。

(3)String readLine():读取一文本行。该方法遇到以下字符或者字符串认为当前行结束:‘\n’(换行符),’\r’(回车符),’\r\n’(回车换行)。返回值为该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回null。

代码实例:

package java_io;  import java.io.BufferedReader;   import java.io.File;   import java.io.FileNotFoundException;   import java.io.FileReader;   import java.io.IOException;    public class TestReader {        public static void main(String[] args) {           TestReader testReader = new TestReader();         String path = "C:\\Users\\luoguohui\\Desktop\\readerTest.txt";           testReader.readFileByFileReader(path);          testReader.readFileByBufferedReader(path);      }      public void readFileByFileReader(String path){         FileReader fileReader = null;          try {             fileReader = new FileReader(path);               char[] buf = new char[1024]; //每次读取1024个字符             int temp = 0;              System.out.println("readFileByFileReader执行结果:");             while ((temp = fileReader.read(buf)) != -1) {                   System.out.print(new String(buf, 0, temp));               }             System.out.println();         } catch (Exception e) {             e.printStackTrace();         } finally { //像这种i/o操作尽量finally确保关闭             if (fileReader!=null) {                 try {                     fileReader.close();                 } catch (IOException e) {                     e.printStackTrace();                 }             }         }     }      public void readFileByBufferedReader(String path){         File file = new File(path);           if (file.isFile()) {               BufferedReader bufferedReader = null;               FileReader fileReader = null;               try {                   fileReader = new FileReader(file);                   bufferedReader = new BufferedReader(fileReader);                   String line = bufferedReader.readLine();                    System.out.println("readFileByBufferReader执行结果:");                 while (line != null) {                       System.out.println(line);                        line = bufferedReader.readLine();                   }               } catch (FileNotFoundException e) {                   e.printStackTrace();               } catch (IOException e) {                   e.printStackTrace();               } finally {                   try {                       fileReader.close();                       bufferedReader.close();                   } catch (IOException e) {                       e.printStackTrace();                   }               }           }       }  }  

上面代码用到finally,关于finally虽然与I/O无关,不过这里还是说一下:

1、不管有木有出现异常,finally块中代码都会执行;

2、当try和catch中有return时,finally仍然会执行;

3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;

4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。

readerTest.txt文本内容:

这里写图片描述

执行结果:

这里写图片描述

2.3、FileWriter和BufferWriter的使用

FileWriter的常用构造有以下四种:

(1)FileWriter(String fileName):根据文件名创建FileWriter对象。

(2)FileWriter(String fileName,boolean append):根据文件名创建FileWriter对象,append参数用来指定是否在原文件之后追加内容。

(3)FileWriter(File file):根据File对象创建FileWriter对象。

(4)FileWriter(File file,boolean append):根据File对象创建FileWriter对象,append参数用来指定是否在原文件之后追加内容。

FileWriter的常用方法包括以下几种:

(1)void writer(int c):向文件中写入正整数c代表的单个字符。

(2)void writer(char[] cbuf):向文件中写入字符数组cbuf。

(3)void writer(char[] cbuf,int off, in len):向文件中写入字符数组cbuf从偏移位置off开始的len个字符。

(4)void writer(String str):向文件中写入字符串str,注意此方法不会在写入完毕之后自动换行。

(5)void writer(String str,int off,int len):向文件中写入字符串str的从位置off开始、长度为len的一部分子串。

(6)Writer append(char c):向文件中追加单个字符c。

(7)Writer append(CharSequence csq):向文件中追加csq代表的一个字符序列。Char