一、字符流 (也叫转换流)
文件字符流
字符流的两个抽象父类:字符输出流:Writer 和字符输入流:Reader
1、字符输出流:Writer
- 使用字符输出流写入数据:使用 Writer 它的子类 OutputStreamWriter 类
- OutputStreamWriter 类的构造方法
- public OutputStreamWriter(OutputStream out):根据默认编码把字节流的数据转换为字符流
- public OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流
- 使用构造方法的 Demo 代码示例:
//创建字符输出流对象,并且根据默认编码把字节流的数据转换为字符流 OutputStreamWriter oswA = new OutputStreamWriter( new FileOutputStream("a.txt")); //创建字符输出流对象,并且根据默认编码把字节流的数据转换为字符流 OutputStreamWriter oswB = new OutputStreamWriter( new FileOutputStream("b.txt"),"UTF-8");
- OutputStreamWriter 类的构造方法
-
OutputStreamWriter 类的成员方法
-
public void write(int c):写一个字符
-
public void write(char[] cbuf):写一个字符数组
-
public void write(char[] cbuf,int off,int len):写一个字符数组的一部分
-
public void write(String str):写一个字符串
-
public void write(String str,int off,int len):写一个字符串的一部分
-
flush():刷新缓冲区
-
close():关闭流对象
- Demo代码示例:
public class OutputStreamWriterDemo { public static void main(String[] args) throws IOException { // 创建对象 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt")); // 写数据 // public void write(int c):写一个字符 osw.write('a'); osw.write(97); osw.write("\r\n");//换行 // public void write(char[] cbuf):写一个字符数组 char[] chs = {'a','b','c','d','e'}; osw.write(chs); osw.write("\r\n");//换行 // public void write(char[] cbuf,int off,int len):写一个字符数组的一部分 osw.write(chs,1,3); osw.write("\r\n");//换行 // public void write(String str):写一个字符串 osw.write("希望早日实现世界和平"); osw.write("\r\n");//换行 // public void write(String str,int off,int len):写一个字符串的一部分 osw.write("123456789", 0, 3);//这是的0,3意思是从下标为0的字符开始向后写3个 osw.write("\r\n");//换行 // 刷新缓冲区 osw.flush(); osw.write("abcdefg", 1, 3); // 释放资源 osw.close(); } }
运行结果:
-
-
close() 和 flush() 的区别
- close() 关闭流对象,但是先刷新一次缓冲区。关闭之后,流对象不可以继续再使用了。
- flush() 仅仅刷新缓冲区,刷新之后,流对象还可以继续使用。
2、字符输入流:Reader
- 使用字符输入流读取数据:使用 Reader它的子类 InputStreamReader 类
- InputStreamReader 类的构造方法
- public InputStreamReader(InputStream in):用默认的编码读取数据
- public InputStreamReader(InputStream in,String charsetName):用指定的编码读取数据
- 使用构造方法的 Demo 代码示例:
//创建字符输入流对象,并且根据默认编码把字节流的数据转换为字符流 InputStreamReader oswA = new InputStreamReader( new FileInputStream("a.txt")); //创建字符输入流对象,并且根据默认编码把字节流的数据转换为字符流 InputStreamReader oswB = new InputStreamReader( new FileInputStream("b.txt"),"UTF-8");
- InputStreamReader 类的构造方法
-
InputStreamReader 类的成员方法
-
public int read():一次读取一个字符
-
public int read(char[] cbuf):一次读取一个字符数组
-
close():关闭流对象
- Demo代码示例:
public class InputStreamReaderDemo { public static void main(String[] args) throws IOException { InputStreamReaderDemo isrd = new InputStreamReaderDemo (); isrd.readA(); } // 一次读取一个字符 public void readA() throws IOException{ // 创建对象 InputStreamReader isr = new InputStreamReader(new FileInputStream( "osw.txt")); // 一次读取一个字符 int ch = 0; while ((ch = isr.read()) != -1) { System.out.print((char) ch); } // 释放资源 isr.close(); } // 一次读取一个字符数组 public void readB() throws IOException{ // 创建对象 InputStreamReader isr = new InputStreamReader(new FileInputStream( "osw.txt")); // 一次读取一个字符数组 char[] chs = new char[1024]; int len = 0; while ((len = isr.read(chs)) != -1) { System.out.print(new String(chs, 0, len)); } // 释放资源 isr.close(); } }
运行结果:
无论调用那个方法所得到的结果都是一样的。
-
3、字符输入流和字符输出流的简化版本
- 我们在使用字符流的时候,会发现字符流的类型都特别长。所以,为了简化我们的书写,转换流提供了对应的子类。
- FileWriter == OutputStreamWriter
- FileReader == InputStreamReader
- 这两个子类的使用方式和它们的父类使用的方式是完全一样的。
- 使用字符流复制文件 Demo 代码示例:
运行结果:略。。。。。和之前复制的结果是一样的。public class CopyFileDemo { public static void main(String[] args) throws IOException { //指定数据获取源 /* FileReader extends InputStreamReader*/ FileReader reader = new FileReader("osw.txt"); //指定一个封装路径 /*FileWriter extends OutputStreamWriter*/ FileWriter writer = new FileWriter("bbb.txt"); // 一次一个字符数组 char[] chs = new char[1024]; int len = 0; while ((len = reader.read(chs)) != -1) { writer.write(chs,0, len); writer.flush(); } // 数据量大会乱码 /* int i = 0; while ((i = reader.read()) != -1){ writer.write(String.valueOf(reader)); }*/ //关闭资源 reader.close(); writer.close(); } }
- 这两个子类的使用方式和它们的父类使用的方式是完全一样的。
4、字符缓冲流
字节流中有字节缓冲流的存在,那么字符流中也一定有着字符缓冲流的存在。并且字符缓冲流和字节缓冲流的作用相同,只是操作的数据不同而已。但是字符缓冲流中有着自己独有的方法,下面来一一演示。
- BufferedWriter:字符缓冲输出流
- BufferedWriter 类独有的成员方法
- public void newLine():根据系统来决定换行符
- BufferedWriter 类独有的成员方法
- 字符缓冲输出流 写入数据 Demo代码示例:
运行结果://字符缓冲流 /*将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。*/ public class Demo01_BufferedWriter { public static void main(String[] args) throws Exception { //创建创建一个字符写入流对象,并指定一个文件名称,文件存在便覆盖文件不存在便创建 FileWriter file = new FileWriter("ddd.txt"); // 为了提高写入流的效率加入了缓冲技术,增加数据写入效率 BufferedWriter writer = new BufferedWriter(file); //write() 存储数据 for (int i = 0; i <= 50000; i++) { writer.write(i+"、我正在学习Java的IO流"); //newLine() 换行 writer.newLine(); } writer.close(); } }
- BufferedReader:字符缓冲输入流
- BufferedReader 类独有的成员方法
- public String readLine():一次读取一行数据
- BufferedReader 类独有的成员方法
-
字符缓冲输入流 写入数据 Demo代码示例:
public class Demo02_BufferedReader { public static void main(String[] args) throws Exception{ //创建读取流对象,并指定读取的文件 FileReader reader = new FileReader("ddd.txt"); //添加读取缓冲技术,提高数据读取效率 BufferedReader buf = new BufferedReader(reader); // 一次读取一行数据 String line = null; while ((line = buf.readLine()) != null) { System.out.println(line); } buf.close(); } }
运行结果:
- 使用字符缓冲流复制文件
- Demo代码示例:
public class Demo03_IO_CopyFile { public static void main(String[] args) throws Exception{ //指定数据源 BufferedReader reader = new BufferedReader(new FileReader("ddd.txt")); //指定数据封装地址 BufferedWriter writer = new BufferedWriter(new FileWriter("java.txt")); String str = null; //readLine():读取一行数据 while ((str = reader.readLine()) != null){ writer.write(str); //newLine()换行 writer.newLine(); writer.flush(); } reader.close(); writer.close(); } } //要切记, readLine()和newLine()是BufferedReader和BufferedWriter 的特殊功能。
- Demo代码示例: