Java IO流字符流简介及常用字符流的基本使用
字符流分为输入字符流(Writer)和输出字符流(Reader),这两种字符流及其子类字符流都有自己专门的功能。在编码中我们常用的输出字符流有FileWriter、PrintWriter等,而常用的输入字符流有StringReader、FileReader、BufferedReader和InputStreamReader等等。Writer是用于写入字符流的抽象类。它的子类必须实现的唯一方法是write(char [],int,int),flush()和close()。 而Reader是用于读取字符流的抽象类。它的子类必须实现的唯一方法是read(char [],int,int)和close()。我们在使用Writer和Reader的过程中,可以通过继承的方式实现,同时我们也可以在继承了Writer或Reader的子类中将重写这里定义父类中已有的一些方法,来实现我们想要的功能。
字符流的结构体系图为(JDK 1.8):
输入字符流(Writer)和输出字符流(Reader)咋区分?
就简单的用磁盘和内存来说,以内存为核心。从内存出来的叫输出,进入内存的叫输入。那么从内存中把流输出写入到磁盘上的就是输出字符流,从磁盘上读取数据写入到内存中的就叫输入流。不知这样说是否合理,有问题还望大家多多指教。
下面来看看常用的几种字符流的使用:
1、FileReader & FileWriter
FileReader类从InputStreamReader类继承而来,该类按字符读取流中数据。它的构造函数假定默认字符编码和默认字节缓冲区大小是适当的。 若要自己来指定这些值,需要在FileInputStream上构造一个InputStreamReader。 FileReader是用于读取字符流,要读取原始字节流,请考虑使用FileInputStream。而FileWriter类从OutputStreamWriter类继承而来,该类按字符向流中写入数据。它的构造函数假定默认字符编码和默认字节缓冲区大小是可以接受的。若也要自己指定这些值,则需要在FileOutputStream上构造一个OutputStreamWriter。 FileWriter类创建对象之后所传入的文件是否可用或是否可能被创建取决于底层平台,特别是某些平台允许一次只能打开一个文件来写入一个FileWriter (或其他文件写入对象)。 在这种情况下,如果所涉及的文件已经打开,则此类中的构造函数将失败。FileWriter是用于写入字符流,要编写原始字节流,请考虑使用FileOutputStream。
示例代码:
1 package com.tianjh.io.writer; 2 3 import java.io.*; 4 5 /** 6 * Created on 2020/12/15 7 * $FileReaderWriterDemo 包含FileWriter、FileReader的简单使用 8 * <p> 9 * FileWriter 是向指定的文件写入数据,write方法会把字符一个一个的写入磁盘中 10 * FileReader 是向指定的文件读取数据,read方法会一个一个字符的从磁盘往回读数据 11 * 12 * @author tianjh 13 */ 14 public class FileReaderWriterDemo { 15 public static void main(String[] args) { 16 17 // 声明一个文件 18 String fileName = "D:\\hello.txt"; 19 // 实例化一个file对象 20 File file = new File(fileName); 21 /* 22 * 1.使用FileWriter的write向磁盘上写文件 23 * write方法会把字符一个一个的写入磁盘中 24 */ 25 try { 26 // 实例化一个fileWriter对象 27 FileWriter fileWriter = new FileWriter(file); 28 fileWriter.write(99); 29 fileWriter.write("您好!"); 30 fileWriter.write("hello world!"); 31 fileWriter.flush(); 32 // 关闭流,释放资源文件 33 fileWriter.close(); 34 } catch (IOException e) { 35 e.printStackTrace(); 36 } 37 38 /* 39 * 2.使用FileReader的read方法从磁盘上读入文件 40 * read方法会一个一个字符的从磁盘往回读数据 41 */ 42 try { 43 int a; 44 // 1. 输出指定文件的每个字节的ASCII码 45 FileReader fileReader = new FileReader(fileName); 46 while ((a = fileReader.read()) != -1) { 47 // 输出指定文件的每个字节的ASCII码 48 System.out.print(a + " "); 49 // expected output: 99 24744 22909 65281 104 101 108 108 111 32 119 111 114 108 100 33 50 } 51 System.out.println(); 52 fileReader.close(); 53 54 // 2. 输出每个字节ASCII码所对应的字符 55 FileReader fileReader1 = new FileReader(fileName); 56 while ((a = fileReader1.read()) != -1) { 57 // 输出每个字节ASCII码所对应的字符 58 System.out.print((char) a); 59 // expected output: c您好!hello world! 60 } 61 fileReader1.close(); 62 System.out.println(); 63 } catch (IOException e) { 64 e.printStackTrace(); 65 } 66 } 67 }
测试结果:
写入到hello.txt文件之后的数据为:
2、PrintWriter
PrintWriter将对象的格式化表示形式打印到文本输出流。这个类实现了全部在PrintStream中找到的所有打印方法。但它不包含用于编写原始字节的方法,程序应使用未编码的字节流。它与PrintStream类不同,PrintStream是针对字节流的,而PrintWriter是针对字符流的。如果PrintWriter启用自动刷新,它只会在调用的println,printf,或format方法来完成,而不是当一个换行符恰好是输出。这些方法使用平台自己的行分隔符而不是换行符。这个类中的方法不会抛出IO异常,尽管它的一些构造函数可能会抛出异常。我们可以通过调用checkError()方法查询是否发生错误。
示例代码:
1 package com.tianjh.io.writer; 2 3 import java.io.PrintWriter; 4 5 /** 6 * Created on 2020/12/15 7 * 8 */ 9 public class PrintWriterDemo { 10 public static void main(String[] args) throws Exception { 11 String fileName = "D:\\hello.txt"; 12 String s1 = "hello world!"; 13 String s2 = "您们好!"; 14 PrintWriter printWriter = new PrintWriter(fileName); 15 printWriter.println(s1); 16 printWriter.println(s2); 17 printWriter.close(); 18 } 19 }
测定结果:
3、StringReader
StringReader是一个字符流,其源是一个字符串。它主要用于处理字符串。
示例代码:
1 package com.tianjh.io.reader; 2 3 import java.io.IOException; 4 import java.io.StringReader; 5 6 /** 7 * Created on 2020/12/15 8 * $StringReaderDemo 测试使用StringReader 9 * 10 */ 11 public class StringReaderDemo { 12 public static void main(String[] args) throws IOException { 13 String s = "hello,world!"; 14 s = s + "我是一条测试数据"; 15 System.out.println(s); 16 // expected output: hello,world!我是一条测试数据 17 18 // 实例化一个stringReader对象,使用read方法进行读取 19 StringReader stringReader = new StringReader(s); 20 int a; 21 while ((a = stringReader.read()) != -1) { 22 System.out.print((char) a); 23 // expected output: hello,world!我是一条测试数据 24 } 25 System.out.println(); 26 } 27 }
输出结果:
5、BufferedReader
BufferedReader它的用法和BufferedInputStream类似,只是它们一个一个处理字符,一个处理字节。BufferedReader用来处理字符。BufferedInputStream的使用可参考https://www.cnblogs.com/jhtian/p/14115355.html
示例代码:
package com.tianjh.io.reader; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; /** * Created on 2020/12/15 * $BufferedReaderDemo 的基本使用 * */ public class BufferedReaderDemo { public static void main(String[] args) throws IOException { // 声明一个文件 String fileName = "D:\\hello.txt"; String s2; StringBuilder s3 = new StringBuilder(); FileReader fileReader = new FileReader(fileName); BufferedReader bufferedReader = new BufferedReader(fileReader); while ((s2 = bufferedReader.readLine()) != null) { s3.append(s2); } System.out.println(s3); // expected output: hello world!您们好! bufferedReader.close(); } }
输出结果: