课程笔记Day19
- 字符文件流
- 转换流
- 字符缓冲流
第一章 字符文件流
第01节 基础理论
为什么需要使用字符流呢?
因为字节流操作文本文件的时候,容易出现 中文乱码问题。这种情况下,我们需要使用字符流。
例如:
将文本文件的数据,读取到控制台当中,展示结果(采用字节流)
编码表
介绍公式
char = byte + 编码表;
字符 = 字节(0和1) + 编码表;
//字符流的由来就是 字节流和编码表的组合。
第02节 FileWriter
字符文件输出流 FileWriter
构造方法
方法API | 方法说明 |
---|---|
FileWriter(String) | 参数1:文件的路径 |
FileWriter(String,boolean) | 参数1:文件的路径 参数2:是否开启追加写,默认false |
FileWriter(File) | 参数1:文件的对象 |
FileWriter(File,boolean) | 参数1:文件的对象 参数2:是否开启追加写,默认false |
常用方法,来自于父类的方法
方法API | 方法说明 |
---|---|
void write(int) | 参数1:写入的字符数据 |
void write(char[]) | 参数1:写入的字符数组数据 |
void write(char[],int,int) | 参数1:写入的字符数组数据,参数2:开始索引,参数3:写几个数据 |
void write(String) | 参数1:写入的字符数组数据 |
void write(String,int,int) | 参数1:写入的字符数组数据,参数2:开始索引,参数3:写几个数据 |
void flush() | 刷新流对象,将内存当中的数据刷新到硬盘当中 |
void close() | 这里的 close()方法表示断开和操作系统之间的关联关系 |
第03节 FileReader
字符文件输入流 FileReader
构造方法
方法API | 方法说明 |
---|---|
FileReader(String) | 参数1:文件的路径 |
FileReader(File) | 参数1:文件的对象 |
常用方法
方法API | 方法说明 |
---|---|
int read() | 一次读取一个字符,返回字符对应的整数值 |
int read(int[]) | 一次读取一个字符数组,返回读取到的字符数组有效长度 |
int read(char[],int,int) | 一次读取一个字符数组的一部分,返回读取到的字符数组有效长度 |
void close() | 释放资源,断开程序和操作系统之间的关联关系 |
第二章 转换流
第01节 OutputStreamWriter
//目标:学习OutputStreamWriter的快速入门
@SuppressWarnings("all")
public class Test01 {
public static void main(String[] args) throws IOException {
String path = "JavaSEDay19\\dir\\测试04.txt";
//1.创建对象
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(path),"GBK");
//2.读写数据
osw.write("定浩和腚耗");
osw.flush();
//3.释放资源
osw.close();
}
}
第02节 InputStreamReader
//目标:学习 InputStreamReader 的快速入门
public class Test02 {
public static void main(String[] args) throws IOException {
String path = "JavaSEDay19\\dir\\测试03.txt";
//1.创建对象
InputStreamReader isr = new InputStreamReader(new FileInputStream(path),"GBK");
//2.读写数据
int ch;
while((ch = isr.read())!=-1){
System.out.print((char)ch);
}
//3.释放资源
isr.close();
}
}
第03节 编码转换
将一个 gbk 格式的文件,转换成 utf-8格式。
分析:
原始文件 gbk 格式 ---【InputStreamReader】---> 读取到程序当中 --【OutputStreamWriter】--> 目标文件 utf-8格式
注意:
之前是什么格式的文件,读取的时候,就需要采用什么编码。
写出的过程,需要转换编码。
读:gbk
写:utf-8
代码
//练习:编码转换 GBK --> UTF-8
@SuppressWarnings("all")
public class Test03 {
public static void main(String[] args) throws IOException {
String spath = "C:\\Users\\chenhaochuan\\Desktop\\新建文件夹\\hello.txt";
String dpath = "JavaSEDay19\\dir\\目标文件03.txt";
//1.创建对象
InputStreamReader isr = new InputStreamReader(new FileInputStream(spath),"GBK");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(dpath),"UTF-8");
//2.读写数据
int ch;
while ((ch = isr.read())!=-1){
osw.write(ch);
osw.flush();
}
//3.释放资源
isr.close();
osw.close();
}
}
第三章 字符缓冲流
第01节 BufferedWriter
字符缓冲输出流 BufferedWriter
构造方法
方法API | 方法说明 |
---|---|
BufferedWriter(Writer) | 参数1:字符输出流的对象 |
BufferedWriter(Writer,int) | 参数1:字符输出流的对象,参数2:缓冲区大小 |
常用方法
方法API | 方法说明 |
---|---|
void write(String) | 参数:字符串 |
void newLine() | 写换行符,不区分操作系统 |
void flush() | 刷新IO流 |
void close() | 释放资源 |
第02节 BufferedReader
字符缓冲输入流 BufferedReader
构造方法
方法API | 方法说明 |
---|---|
BufferedReader(Reader) | 参数1:字符输入流的对象 |
BufferedReader(Reader,int) | 参数1:字符输入流的对象 参数2:缓冲区的大小 |
常用方法
方法API | 方法说明 |
---|---|
String readLine() | 一次性读取一行数据,不会读取换行符 |
void close() | 释放资源,断开和操作系统之间的关联 |
第03节 复制文件案例
//练习:采用字符缓冲流实现文件复制代码(重点)特殊方法
@SuppressWarnings("all")
public class Test03 {
public static void main(String[] args) throws IOException {
String spath = "JavaSEDay19\\dir\\测试05.txt";
String dpath = "JavaSEDay19\\dir\\目标文件04.txt";
//1.创建对象
BufferedReader br = new BufferedReader(new FileReader(spath));
BufferedWriter bw = new BufferedWriter(new FileWriter(dpath));
//2.读写数据
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine(); //换行
bw.flush(); //刷新
}
//3.释放资源
br.close();
bw.close();
}
}
第04节 同文反转案例
//题目:同文反转【正确的写法】
@SuppressWarnings("all")
public class Test05 {
public static void main(String[] args) throws IOException {
String path = "JavaSEDay19\\dir\\hello.txt";
//1. 将文件的数据读取到集合当中
BufferedReader br = new BufferedReader(new FileReader(path));
ArrayList<String> array = new ArrayList<>();
//读取数据
String line;
while((line = br.readLine())!=null){
array.add(line);
}
br.close();
//2. 将集合的数据写回到文件当中
BufferedWriter bw = new BufferedWriter(new FileWriter(path));
//循环遍历集合,准备写数据
for (String s : array) {
//反转操作
StringBuilder sb = new StringBuilder(s);
String str = sb.reverse().toString();
//写回数据
bw.write(str);
bw.newLine(); //换行
bw.flush(); //刷新
}
bw.close();
}
}
今日作业
AgeException自定义异常
public class AgeException extends Exception {
public AgeException(String message) {
super(message);
}
Student 类
public class Student {
private String name;
private int age;
private String gender;
public Student() {
}
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
测试类:
package com.blb.test;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) throws IOException, AgeException {
// 1、将第01题,改写一下,数据来自于 键盘录入,再去实现第1题的功能。
// 2、在键盘录入的过程当中,加入 年龄的处理问题。如果年龄 低于0或者高于 200 则出现年龄异常(采用自定义的 AgeException 完成)
// 3、增加功能,在保存到 文件 studentinfo.txt 的过程当中,增加排序功能。
// 要求,按照年龄的 从大到小的顺序排列。
Scanner in = new Scanner(System.in);
List<Student> list= new ArrayList<>();
System.out.println("请输入录入学生人数:");
int num=in.nextInt();
for (int i = 0; i < num; i++) {
System.out.println("请输入学生的姓名:");
Student s1=new Student();
String name=in.next();
s1.setName(name);
System.out.println("年龄为:");
int age= in.nextInt();
if(age<0 || age>200){
throw new AgeException("年龄出现异常!!!");
}
s1.setAge(age);
System.out.println("性别为:");
String sex=in.next();
s1.setGender(sex);
list.add(s1);
}
String path="day19\\dir\\studentInfo.txt";
//1. 将文件的数据读取到集合当中
BufferedWriter bw = new BufferedWriter(new FileWriter(path));
String line;
List<Student> list1 = list.stream().sorted((f1, f2) -> Long.compare(f2.getAge(), f1.getAge())).collect(Collectors.toList());
for (Student student : list1) {
String str=student.getName()+"@"+student.getAge()+"@"+student.getGender();
bw.write(str);
bw.newLine();
bw.flush();
System.out.println(student);
}
bw.close();
}
private static void method02() throws IOException {
//将上一题当中的数据。文本文件 studentinfo.txt 的数据,读取到集合当中。
//集合固定为 ArrayList<Student> 并且遍历集合。
//Student 类当中,需要包含有:name age gender
String path="day19\\dir\\studentInfo.txt";
//1. 将文件的数据读取到集合当中
BufferedReader br = new BufferedReader(new FileReader(path));
ArrayList<String> array = new ArrayList<>();
//2.读取数据
String line;
while((line = br.readLine())!=null){
array.add(line);
}
for (String s : array) {
System.out.println(s);
}
//3.释放资源
br.close();
}
private static void method01() throws IOException {
存在这样的学生数据:(Student类)
/*姓名:张三,年龄: 23,性别:女
姓名:李四,年龄 24,性别:男
姓名:王五,年龄 25, 性别:女
1、将这些数据存储到集合当中(内存存储)
2、将集合数据存储到文件当中(硬盘存储) studentinfo.txt
存储的格式如下:
张三@23@女
李四@24@男
王五@25@女*/
Student s1=new Student("张三",23,"女");
Student s2=new Student("李四",24,"男");
Student s3=new Student("王五",25,"女");
List<Student> list= new ArrayList<>();
list.add(s1);
list.add(s2);
list.add(s3);
String path="day19\\dir\\studentInfo.txt";
String[] str= new String[list.size()];
int index=0;
for (Student student : list) {
str[index]=student.getName()+"@"+student.getAge()+"@"+student.getGender();
index++;
}
BufferedWriter bw= new BufferedWriter(new FileWriter(path));
for (String s : str) {
bw.write(s);
bw.newLine();
bw.flush();
}
bw.close();
}
}