简介
FileReader是读取字符流的类,继承于InputStreamReader类,用于将内容通过字符流的方式从文件读取到应用程序中
源码分析
InputStreamReader
InputStreamReader 是字节流通向字符流的桥梁,它使用指定的 charset 读取字节并将其解码为字符。
它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。 每次调用 InputStreamReader 中的一个 read() 方法**都会导致从底层输入流读取一个或多个字节**。
要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。
package java.io;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;import sun.nio.cs.StreamDecoder;/*** @see BufferedReader* @see InputStream* @see java.nio.charset.Charset** @author Mark Reinhold* @since JDK1.1*/public class InputStreamReader extends Reader {// 流解码器,从字节到字符的解码过程严重依赖StreamDecoder类及其方法,通篇都在使用这个类private final StreamDecoder sd;/*** 构造方法,传入一个字节输入流* @param in An InputStream*/public InputStreamReader(InputStream in) {// 调用父类构造方法:Reader(Object lock)super(in);try {// 构建流解码类sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object} catch (UnsupportedEncodingException e) {// The default encoding should always be availablethrow new Error(e);}}/*** 构造方法,传入字节输入流以及指定字符集名称(如utf-8)* @param in* An InputStream** @param charsetName* The name of a supported* {@link java.nio.charset.Charset charset}*/public InputStreamReader(InputStream in, String charsetName) throws UnsupportedEncodingException{super(in);if (charsetName == null)throw new NullPointerException("charsetName");sd = StreamDecoder.forInputStreamReader(in, this, charsetName);}/*** 构造方法,创建使用给定字符集的 InputStreamReader。* @param in An InputStream* @param cs A charset* @since 1.4* @spec JSR-51*/public InputStreamReader(InputStream in, Charset cs) {super(in);if (cs == null)throw new NullPointerException("charset");sd = StreamDecoder.forInputStreamReader(in, this, cs);}/*** 创建使用给定字符集解码器的 InputStreamReader* @param in An InputStream* @param dec A charset decoder** @since 1.4* @spec JSR-51*/public InputStreamReader(InputStream in, CharsetDecoder dec) {super(in);if (dec == null)throw new NullPointerException("charset decoder");sd = StreamDecoder.forInputStreamReader(in, this, dec);}/*** 获取此字符流使用的字符编码的名称* @return The historical name of this encoding, or* <code>null</code> if the stream has been closed* @see java.nio.charset.Charset* @revised 1.4* @spec JSR-51*/public String getEncoding() {return sd.getEncoding();}/*** 读取单个字符* @return The character read, or -1 if the end of the stream has been* reached*/public int read() throws IOException {return sd.read();}/*** 从流中读入length个字符内容,并插入到字符数组的offset位置后* 返回读取到的字符个数,返回-1表示到了文件结尾* @param cbuf Destination buffer 字符数组* @param offset Offset at which to start storing characters* @param length Maximum number of characters to read* @return The number of characters read, or -1 if the end of the* stream has been reached*/public int read(char cbuf[], int offset, int length) throws IOException {return sd.read(cbuf, offset, length);}/*** 是否已经准备好被读取*/public boolean ready() throws IOException {return sd.ready();}// 关闭字符流,同时关闭解码器public void close() throws IOException {sd.close();}}
可见,InputStreamReader作为字节流和字符流转换的桥梁,内部通过**StreamDecoder类执行读内容转换的操作**
FileReader
package java.io;/*** 文件字符输入流* @see InputStreamReader* @see FileInputStream** @author Mark Reinhold* @since JDK1.1*/public class FileReader extends InputStreamReader {/*** 构造方法,传入文件路径,内部构建了一个文件字节输入流,调用父类构造方法* @param fileName the name of the file to read from*/public FileReader(String fileName) throws FileNotFoundException {super(new FileInputStream(fileName));}/*** 构造方法,传入文件对象,内部构建了一个文件字节输入流,调用父类构造方法* @param file the <tt>File</tt> to read from*/public FileReader(File file) throws FileNotFoundException {super(new FileInputStream(file));}/*** 构造方法,传入文件描述符,内部构建了一个文件字节输入流,调用父类构造方法* @param fd the FileDescriptor to read from*/public FileReader(FileDescriptor fd) {super(new FileInputStream(fd));}}
可见,FileReader核心操作都是依赖于父类InputStreamReader的方法去执行的。
简单使用
现有一文件如下:
package com.java.io;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.util.Arrays;/*** @description FileReader 示例* @date: 2021-01-18 22:45*/public class FileReaderExample {public static void main(String[] args) {commonExample();}public static void commonExample() {String filePath = "D:\\IDEAWorkSpace\\JAVALearn\\io\\src\\resource\\file.txt";FileReader fileReader = null;try {fileReader = new FileReader(filePath);// 如果文件字符流已准备好if(fileReader.ready()){char[] contents = new char[30];int read = fileReader.read(contents); // 读取内容到contents数组System.out.println("读取到了"+read+"个字符");System.out.print("读取到的内容:");for(int i=0;i<contents.length;i++){// 如遇\0表示为空if(contents[i] == '\0'){break;}System.out.print(contents[i]+",");}}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}finally {if(null != fileReader){try {fileReader.close();} catch (IOException e) {e.printStackTrace();}}}}}
输出结果:
读取到了23个字符读取到的内容:拜, ,拜, ,我, ,的, ,乖, ,乖, ,隆, ,地, ,动, ,!, ,!, ,!
总结
1、FileReader是读取字符流的类,继承于InputStreamReader类,用于将内容通过字符流的方式从文件读取到应用程序中
2、InputStreamReader 是字节流通向字符流的桥梁,它使用指定的 charset 读取字节并将其解码为字符。
它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。 每次调用 InputStreamReader 中的一个 read() 方法**都会导致从底层输入流读取一个或多个字节。
3、InputStreamReader作为字节流和字符流转换的桥梁,内部通过**StreamDecoder类执行读内容转换的操作
4、FileReader核心操作都是依赖于父类InputStreamReader的方法去执行的。
