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