文章目录
- 字符流的使用
- 文件字符输入流
- 创建字符输入流
- 字符输入流读取
- 文件字符输出流
- 创建字符输出流
- 字符输出流写入
字符流的使用
字节流读取中文输出会存在什么问题?
- 会乱码。或者内存溢出。
读取中文输出,哪个流更合适,为什么?
- 字符流更合适,最小单位是按照单个字符读取的。
字符输入输出流的实现类分别是FileReader和FileWriter
文件字符输入流
创建字符输入流
文件字符输入流:实现类FileReader
作用:以内存为基准,把磁盘文件中的数据以字符的形式读取到内存中去。
构造器 | 说明 |
---|---|
public FileReader(File file) | 创建字符输入流管道与源文件对象接通 |
public FileReader(String pathname) | 创建字符输入流管道与源文件路径接通 |
public static void main(String[] args) throws Exception {
// 创建字符输入流管道与源文件对象接通
Reader fr = new FileReader(new File("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.txt"));
}
public static void main(String[] args) throws Exception {
// 创建字符输入流管道与源文件路径接通
Reader fr = new FileReader("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.txt");
}
字符输入流读取
文件字符流的读取API如下:
方法名称 | 说明 |
---|---|
read() | 每次读取一个字符, 返回读取内容的编号,如果字符已经没有可读的返回-1 |
read(char[] buffer) | 每次读取一个字符数组,返回读取的字符个数,如果字符已经没有可读的返回-1 |
每次读取一个字符: 普通读取 (我们可以发现字符流可以读取中文和英文, 不会出现乱码的问题)
public static void main(String[] args) throws Exception {
// 创建字符输入流管道与源文件路径接通
Reader fr = new FileReader("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.txt");
// 第一次读取文件 返回的是字符编号
int code1 = fr.read();
// 将编号转为字符输出
System.out.println((char) code1); // 我
// 第二次读取
int code2 = fr.read();
System.out.println((char) code2); // a
}
每次读取一个字符: 循环读取 (每次读取一个字符性能较慢)
public static void main(String[] args) throws Exception {
// 创建字符输入流管道与源文件路径接通
Reader fr = new FileReader("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.txt");
int code;
while ((code = fr.read()) != -1) {
System.out.print((char) code); // 我aa我a
}
}
每次读取一个字符数组: 循环读取 (*字符流每次读取一个数组在读取中文不乱码的基础上, 提高了读取的性能)
public static void main(String[] args) throws Exception {
Reader fr = new FileReader("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.txt");
// 创建一个字符数组, 1024表示每次读取1k的字符(注意不是1024kb)
char[] arr = new char[1024];
// 记录每次读取了多少个字符
int len;
while ((len = fr.read(arr)) != -1) {
// 对读取的字符进行解码
String res = new String(arr, 0, len);
System.out.print(res);
}
}
文件字符输出流
字符输入流相比字节输入流更加适合写入文本
创建字符输出流
构造器 | 说明 |
---|---|
public FileWriter(File file) | 创建字符输出流管道与源文件对象接通 |
public FileWriter(File file,boolean append) | 创建字符输出流管道与源文件对象接通,可追加数据 |
public FileWriter(String filepath) | 创建字符输出流管道与源文件路径接通 |
public FileWriter(String filepath,boolean append) | 创建字符输出流管道与源文件路径接通,可追加数据 |
创建字符输出流
public static void main(String[] args) throws Exception {
// 创建字符输出流与源文件对象接通
Writer fw1 = new FileWriter(new File("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.txt"));
// 创建字符输出流与源文件路径接通
Writer fw2 = new FileWriter("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.txt");
}
创建字符输出流, 并由覆盖文件内容设置为追加文件内容(第二个参数设置为true就不会覆盖文件原来的内容)
public static void main(String[] args) throws Exception {
// 创建字符输出流与源文件对象接通, 并设置可追加数据xxx
Writer fw1 = new FileWriter(new File("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.txt"), true);
// 创建字符输出流与源文件路径接通, 并设置可追加数据
Writer fw2 = new FileWriter("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.txt", true);
}
字符输出流写入
字符输出流写数据出去的API
方法名称 | 说明 |
---|---|
write(int c) | 写一个字符 |
write(char[] cbuf) | 写入一个字符数组 |
write(char[] cbuf, int off, int len) | 写入字符数组的一部分 |
write(String str) | 写一个字符串 |
write(String str, int off, int len) | 写一个字符串的一部分 |
write(int c) | 写一个字符 |
与字节输入输出流一样, 字符输出流也有流的刷新与关闭
方法 | 说明 |
---|---|
flush() | 刷新流,还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
示例代码:
写入换行同样是
\r\n
public static void main(String[] args) throws Exception {
// 创建字符输入流的追加管道
Writer fw = new FileWriter("/Users/chenyq/Documents/learn_Java/code/file-io-app/src/test.txt", true);
// 定义一个字符数组
char[] arr = {'我', '爱', 'C', 'h', 'i', 'n', 'a'};
// 定义一个字符串
String str = "我爱学习Java";
// 写入一个字符
fw.write('我');
fw.write(98);
// 写入一个字符数组
fw.write(arr);
// 写入字符数组的一部分
fw.write(arr, 1, 3);
// 写入一个字符串
fw.write(str);
// 写入换行
fw.write("\r\n");
// 写入一个字符串的一部分
fw.write(str, 0, 4);
// 释放资源
fw.close();
}
字符流字节流总结:
字节流适合做一切文件数据的拷贝(音视频,文本)
字节流不适合读取中文内容输出
字符流适合做文本文件的操作(读,写)