字符流的由来:因为数据编码的不同,因而有了对字符进行高效操作的流对象,字符流本质其实就是基于字节流读取时,去查了指定的码表,而字节流直接读取数据会有乱码的问题(读中文会乱码)
-
java将流按照读写单位划分为字节流与字符流.
-
java.io.InputStream 和 java.io.OutputStream是所有字节流的超类
-
而java.io.Reader 和 java.io.Writer则是所有字符流的超类(父类),它们和字节流的超类是平级关系.
-
Reader和Writer是两个抽象类,里面规定了所有字符流都必须具备的读写字符的相关方法.
-
字符流最小读写单位为字符(char),但是底层实际还是读写字节,只是字符与字节的转换工作由字符流完成.
字符输入流的共性方法:
1、public void close() :关闭此流并释放与此流相关联的任何系统资源。
2、public int read(): 从输入流读取一个字符。
3、public int read(char[] arr): 从输入流中读取一些字符,并将它们存储到字符数组 arr 中
字符输出流的基本共性功能方法:
3.1 FileReader类 / FileWriter类 FileReader类1、void write(int c) 写入单个字符。
2、void write(char[] cbuf)写入字符数组。
3、abstract void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索
引,len写的字符个数。
4、void write(String str)写入字符串。
5、void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的
字符个数。
6、void flush()刷新该流的缓冲。
7、void close() 关闭此流,但要先刷新它。
java.io.FileReader类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
- 构造方法
1、FileReader(File file): 创建一个新的 FileReader ,给定要读取的File对象。
2、FileReader(String fileName): 创建一个新的 FileReader ,给定要读取的文件的字符串名称。
public class Test throws IOException{
public static void main(String[] args) {
// (1) 使用File对象创建流对象
File file = new File("fos.txt");
FileReader fr = new FileReader(file);
// (2) 使用文件名称创建流对象
FileReader fr = new FileReader("fos.txt");
}
}
- FileReader读取字符数据
读取字符:read()方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回-1,循环读取
package demo;
import java.io.FileReader;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileReader fr = new FileReader("fos.txt");
// 定义变量,保存数据
int b ;
// 循环读取
while ((b = fr.read())!=-1) {
System.out.print((char)b);
}
// 关闭资源
fr.close();
}
}
FileWriter类
java.io.FileWriter类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。
- 构造方法
1、 FileWriter(File file): 创建一个新的 FileWriter,给定要读取的File对象。
2、FileWriter(String fileName): 创建一个新的 FileWriter,给定要读取的文件的名称。
public class Test{
public static void main(String[] args) throws IOException {
// (1) 使用File对象创建流对象
File file = new File("fos.txt");
FileWriter fw = new FileWriter(file);
// (2) 使用文件名称创建流对象
FileWriter fw = new FileWriter("fos.txt");
}
}
- FileWriter写出数据
写出字符:write(int b) 方法,每次可以写出一个字符数据。
package demo;
import java.io.FileWriter;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("fos.txt");
// 写出数据
fw.write(97); // 写出第1个字符
fw.write("b"); // 写出第2个字符
fw.write("c"); // 写出第3个字符
//关闭资源时,与FileOutputStream不同。 如果不关闭,数据只是保存到缓冲区,并未保存到文件。
//flush():刷新缓冲区
// fw.flush();
fw.close();
}
}
3.2 InputStreamReader 和 OutputStreamWriter ( 转换流 )【注意】关闭资源时,与FileOutputStream不同。 如果不关闭,数据只是保存到缓冲区,并未保存到文件。
java.io.InputStreamReader 和 java.io.OutputStreamWriter
它们是字符流非常常用的一对实现类同时也是一对高级流,实际开发中我们不直接操作它们,但是它们在流连接中是非常重要的一环。
java.io.InputStreamReader是从字节流到字符流的桥梁,它读取字节并使用指定的字符集将其解码为字符。它使用的字符集可以通过名称指定,也可以显式给定,或者可以接受平台的默认字符集。
package demo;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class Test {
public static void main(String[] args) throws IOException {
//将osw.txt文件中的所有文字读取回来.
FileInputStream fis = new FileInputStream("fos.dat");
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
//循环将文件所有字符读取回来
int d;
while((d = isr.read()) != -1){
System.out.print((char)d);
}
//关闭流
isr.close();
}
}
OutputStreamWriter(转换字符输出流)
java.io.OutputStreamWriter是从字符转换为字节流的桥梁
package demo;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class Test {
public static void main(String[] args) throws IOException {
//向文件fos.txt中写入文字
FileOutputStream fos = new FileOutputStream("fos.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
osw.write("我不管,反正公主最可爱");
osw.write("tn");
osw.write("我顶着大太阳,只想为你撑伞");
System.out.println("写出完毕!");
//关闭流
osw.close();
}
}
- 转换流的意义:
3.3 BufferedReader 和 BufferedWriter(缓冲字符流)实际开发中我们还有功能更好用的字符高级流,但是其他的字符高级流都有一个共通点:不能直接连接在字节流上,而实际操作设备的流都是低级流同时也都是字节流,因此不能直接在流连接中串联起来,转换流是一对可以连接在字节流上的字符流,其他的高级字符流可以连接在转换流上,在流连接中起到"转换器"的作用(负责字符与字节的实际转换)
java.io.BufferedWriter 和 java.io.BufferedReader
缓冲字符流内部也有一个缓冲区,读写文本数据以块读写形式加快效率,并且缓冲流有一个特别的功能,可以按行读写文本数据。
BufferedWriter缓冲字符输出流:- 缓冲字符输出流:java.io.PrintWriter
java.io.PrintWriter具有自动行刷新的缓冲字符输出流,实际开发中更常用,它内部总是会自动连接BufferedWriter作为块写加速使用。
java.io.BufferedWriter将文本写入字符输出流,缓冲各个字符,从而提供单个字符,数组和字符串的高效写入.可以指定缓冲区的大小,或者接受默认的大小,在大多数情况下,默认值就足够大了(默认为8k)
package demo;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
public class Test {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
//向文件pw.txt中写入字符串
PrintWriter pw = new PrintWriter("pw.txt","UTF-8");
pw.println("我看过沙漠下暴雨");
pw.println("看过大海亲吻鲨鱼");
pw.println("看过黄昏追逐黎明");
pw.println("没看过你");
System.out.println("写出完毕!");
pw.close();
}
}
- 在流连接中使用PW:
package demo;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class Test {
public static void main(String[] args) throws FileNotFoundException {
//文件字节输出流(是一个低级流),向文件中写入字节数据
FileOutputStream fos = new FileOutputStream("pw.txt",true);
//转换输出流(是一个高级流,且是一个字符流)。1:衔接字符与字节流 2:将写出的字符转换为字节
OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
//缓冲输出流(是一个高级流,且是一个字符流)。块写文本数据加速
BufferedWriter bw = new BufferedWriter(osw);
//具有自动行刷新的缓冲字符输出流
PrintWriter pw = new PrintWriter(bw);
// PrintWriter pw = new PrintWriter(bw,true);
//完成简易记事本。控制台输入的每行字符串都按行写入文件。单独输入exit时退出。
Scanner scanner = new Scanner(System.in);
while(true){
System.out.print("请输入文本内容:");
String line = scanner.nextLine();
if("exit".equalsIgnoreCase(line)){
System.out.println("写出完毕!");
break;
}
pw.println(line);
}
pw.close();
}
}
BufferedReader 缓冲字符输入流
缓冲字符输入流 java.io.BufferedReader 是一个高级的字符流,特点是块读文本数据,并且可以按行读取字符串。
package demo;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class Test {
public static void main(String[] args) throws IOException {
//将当前源程序(Test.java)读取出来并输出到控制台上
// FileInputStream fis = new FileInputStream("./src/demo/Test.java");
//读取fos.daat文件中的数据
FileInputStream fis = new FileInputStream("fos.dat");
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
}
IO总结:



