Java基础 第四节 第十三课
概述
当使用字节流读取文本文件时, 可能会有一个小问题. 就是遇到中文字符时, 可能不会显示完整的字符, 那是因为一个中文字符可能占用多个字节存储. 所以 Java 提供一些字符流类, 以字符为单位读写数据, 专门用于处理文本文件.
字符输入流 (Reader)
java.io.Reader抽象类是表示用于读取字符流的所有类的超类, 可以读取字符信息到内存中. 它定义了字符输入流的基本功能方法.
public void close(): 关闭此流并释放与此流相关联的任何系统资源public int read(): 从输入流读取一个字符public int read(char[] cbuf): 从输入流中读取一些字符,
FileReader 类
java.io.FileReader类是读取字符文件的便利类. 构造时使用系统默认的字符编码和默认字节缓冲流.
- 字符编码: 字节与字符的对应规则. Windows 系统的中文编码默认是 GBK 编写表. idea 中 UTF-8
- 字节缓冲区: 一个字节数组, 用来临时存储字节数据
构造方法
FileReader(File file): 创建一个新的 FileReader, 给定要读取的 File 对象.
FileReader(String fileName):创建一个新的 FileReader, 给定要读取的文件的名称
当你创建一个流对象时, 必须传入一个文件路径. 类似于 FileInputStream. 代码展示:
读取字符数据
读取数据
读取数据: read 方法, 每次可以读取一个字符的数据, 提升为 int 类型, 读取到文件尾, 返回 -1. 循环读取, 代码使用演示:
import java.io.FileReader;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileReader fr = new FileReader("read.txt");
// 定义变量, 保存数据
int b;
// 循环读取
while ((b = fr.read()) != -1){
System.out.println((char)b);
}
// 关闭资源
fr.close();
}
}
输出结果:
程
序
员
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
使用字符数组读取
使用字符数组读取: read(char[] cbuf), 每次读取 b 的长度个字符到数组中, 返回读取到的有效字符个数. 读取到末尾时, 返回 -1. 代码展示:
import java.io.FileReader;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileReader fr = new FileReader("read.txt");
// 定义变量, 保存有效字符个数
int len;
// 定义字符数组, 作为装字符数据的容器
char[] cbuf = new char[2];
// 循环读取
while ((len = fr.read(cbuf))!= -1) {
System.out.println(cbuf);
}
// 关闭资源
fr.close();
}
}
输出结果:
程序
员序
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
获取有效的字符改进, 代码使用演示:
import java.io.FileReader;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileReader fr = new FileReader("read.txt");
// 定义变量, 保存有效字符个数
int len;
// 定义字符数组, 所谓装字符数据的容器
char[] cbuf = new char[2];
// 循环读取
while ((len = fr.read(cbuf)) != -1){
System.out.println(new String(cbuf,0,len));
}
// 关闭资源
fr.close();
}
}
输出结果:
程序
员
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
字符输出流 (writter)
java.io.Writer抽象类是用于写出字符流的所有类的超类, 将指定的字符信息写出到目的地. 它的定义了字节输出流的基本共性功能方法.
void write(int c): 写入单个字符- ```void write(char[] cbuf)````: 写入字符数组
abstract void write(char[] cbuf, int off, int len): 写入字符数组的某一部分, off 字符串的开始 索引, len 写的字符个数.void flush(): 刷新该流的缓冲void close(): 关闭此流, 但要先刷新它
FileWriter 类
```java.io.FileWriter``类是写出字符到文件的便利类. 构造时使用系统默认的字符编码和默认字节缓冲区.
构造方法
FileWriter(File file): 创建一个新的 FileWriter, 给定要读取的 FIle 对象FileWriter(String fileName): 创建一个新的 FileWriter, 给定要读取的文件的名称
当你创建一个流对象时, 必须传入一个文件路径, 类似于 FileOutputStream. 代码展示:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Test18 {
public static void main(String[] args) throws IOException {
// 使用文File对象创建流对象
File file = new File("read.txt");
FileWriter fw1 = new FileWriter(file);
// 使用文件名称创建流对象
FileWriter fw2 = new FileWriter("read.txt");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
基本写出数据
写出字符: write(int b)方法, 每次可以写出一个字符数据. 代码展示:
import java.io.FileWriter;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("read.txt");
// 写出数据
fw.write(97); // 写出第1个字符
fw.write('b'); // 写出第2个字符
fw.write('C'); // 写出第3个字符
fw.write(30000); // 写出第4个字符, 中文编码表中30000对应一个汉字。
/*
注意: 关闭资源时,与FileOutputStream不同
如果不关闭, 数据只是保存到缓冲区, 并未保存到文件
*/
fw.close();
}
}
输出结果:
abC田
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
注:
- 虽然参数为 int 类型四个字节, 但是只会保留一个字符的信息写出
- 未调用 close 方法, 数据只是保存到了缓冲区, 并未写出到文件中
关闭和刷新
因为内置缓冲区的原因, 如果不关闭输出流, 无法写出文字到文件中. 但是关闭的流对象, 是无法继续写出数据的. 如果我们既想写出数据, 又想继续使用流, 就需要 flush 方法了.
flush: 刷新缓冲区, 流对象可以继续使用close: 先刷新缓冲区, 然后通知系统释放资源. 流对象不可以再被使用了.
代码展示:
import java.io.FileWriter;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
// 使用文件名创建流对象
FileWriter fw = new FileWriter("read.txt");
// 写出数据, 通过flush
fw.write("刷"); // 写出第一个字符
fw.flush();
fw.write("新");
fw.flush();
// 写出数据, 通过clsoe
fw.write("关");
fw.close();
fw.write("闭"); // 继续写出第2个字符, 报错java.io.IOException: Stream closed
}
}
输出结果:
刷新关
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
注: 即便是 flush 方法写出了数据, 操作的最后还是要调用 close 方法, 释放系统资源.
写出其他数据
写出字符数组
写出字符数组: write(char[] cbuf)和```write(char[] cbuf, int off, int len), 每次可以写出字符数组中的数据, 用法类似 FileOutputStream. 代码展示:
import java.io.FileWriter;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("read.txt");
// 字符串转换为字符数组
char[] chars = "我是小白".toCharArray();
// 写出字符数组
fw.write(chars); // 程序员
// 写出从索引2开始, 2个字符. 索引2是"程", 两个字符, 也就是"程序"
fw.write(chars,2,2); // 程序
// 关闭资源
fw.close();
}
}
输出结果:
我是小白小白
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
写出字符串
写出字符串: write(String str)和write(String str, int off, int len), 每次可以写出字符串中的数据, 更为方便. 代码展示:
import java.io.FileWriter;
import java.io.IOException;
public class Test22 {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileWriter fw = new FileWriter("read.txt");
// 字符串
String msg = "程序员";
// 写出字符数组
fw.write(msg); //程序员
// 写出从索引2开始, 2个字符. 索引2是"程", 两个字符, 也就是"程序"
fw.write(msg,0,2); // 程序
// 关闭资源
fw.close();
}
}
输出结果:
我是小白小白
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
编写和换行
编辑和换行: 操作类似于 FileOutputStream.
import java.io.FileWriter;
import java.io.IOException;
public class Test23 {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象, 可以续写数据
FileWriter fw = new FileWriter("fw.txt",true);
// 写出字符串
fw.write("你好");
// 写出换行
fw.write("\r\n");
// 写出字符串
fw.write("程序员");
// 关闭资源
fw.close();
}
}
输出结果:
你好
程序员
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
注: 字符流, 只能操作文本文件, 不能操作图片, 视频等非文本文件. 当我们单纯读取或者写文本文件时, 使用字符流, 其他情况使用字节流.
文章来源: iamarookie.blog.csdn.net,作者:我是小白呀,版权归原作者所有,如需转载,请联系作者。
原文链接:iamarookie.blog.csdn.net/article/details/110418954
- 点赞
- 收藏
- 关注作者
评论(0)