ASCII(美国信息交换标准代码):包括了数字,大小写字符和一些常见的标点符号, ASCII码表中没有中文
GBK:window系统默认的码表,兼容ASCII码表,也包含了21003个汉字,一个中文以两个字节的形式存储
Unicode码表:由国际组织ISO 制定,是统一的万国码,IDEA默认使用Unicode的UTF-8编解码格式。以UTF-8编码后一个中文以三个字节的形式存储
因为字节流一次读一个字节,而不管GBK还是UTF-8一个中文都是多个字节,用字节流每次只能读其中的一部分,所以就会出现乱码问题。
方法名 | 说明 |
---|---|
byte[] getBytes() | 使用平台的默认字符集将该 String编码为一系列字节 |
byte[] getBytes(String charsetName) | 使用指定的字符集将该 String编码为一系列字节 |
String(byte[] bytes) | 使用平台的默认字符集解码指定的字节数组来创建字符串 |
String(byte[] bytes, String charsetName) | 通过指定的字符集解码指定的字节数组来创建字符串 |
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Demo01 {
public static void main(String[] args) throws UnsupportedEncodingException {
String str = "落霞与孤鹜齐飞,秋水共长天一色";
//解码
byte[] bytes1 = str.getBytes("utf-8");
byte[] bytes2 = str.getBytes("gbk");
System.out.println("utf-8:"+ Arrays.toString(bytes1));
System.out.println("gbk:"+ Arrays.toString(bytes2));
//编码
String s1 = new String(bytes1, "utf-8");
String s2 = new String(bytes2, "gbk");
System.out.println(s1);
System.out.println(s2);
}
}
字符流在读取纯文本文件时,当遇到中文时会根据码表,读取对应2个字节或者3个字节
Writer: 字符输出流的抽象父类
FileWriter: 字符输出流的常用子类
构造方法:
方法名 | 说明 |
---|---|
FileWriter(File file) | 根据给定的 File 对象构造一个 FileWriter 对象 |
FileWriter(String fileName) | 根据给定的文件名构造一个 FileWriter 对象 |
成员方法:
方法名 | 说明 |
---|---|
void write(int c) | 写一个字符 |
void write(char[] cbuf) | 写入一个字符数组 |
void write(char[] cbuf, int off, int len) | 写入字符数组的一部分 |
void write(String str) | 写一个字符串 |
void write(String str, int off, int len) | 写一个字符串的一部分 |
刷新和关闭的方法:
方法名 | 说明 |
---|---|
flush() | 刷新流,之后还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
import java.io.FileWriter;
import java.io.IOException;
public class Demo02 {
public static void main(String[] args) throws IOException {
//字符输出流对象
FileWriter fileWriter = new FileWriter("day12_exercise\\aaa.txt");
//一次写一个字符
int a = 97;
fileWriter.write(a);//将97对应字符写到aaa.txt
//一次写一个字符数组的一部分
char[] chars = {97, 98, 99, 100};
fileWriter.write(chars,0,2);
//写一个字符串
String line = "落霞与孤鹜齐飞";
fileWriter.write(line);//直接将字符串写到aaa.txt
//刷新
fileWriter.flush();
//释放资源
fileWriter.close();
}
}
Reader: 字符输入流的抽象父类
FileReader: 字符输入流的常用子类
构造方法:
方法名 | 说明 |
---|---|
FileReader(File file) | 在给定从中读取数据的 File 的情况下创建一个新 FileReader |
FileReader(String fileName) | 在给定从中读取数据的文件名的情况下创建一个新 FileReader |
成员方法:
方法名 | 说明 |
---|---|
int read() | 一次读一个字符数据 |
int read(char[] cbuf) | 一次读一个字符数组数据 |
import java.io.FileReader;
import java.io.IOException;
public class Demo03 {
public static void main(String[] args) throws IOException {
FileReader fileReader = new FileReader("day12_exercise\\aaa.txt");
//一次读取一个字符
int cha;
while ((cha = fileReader.read()) != -1){
System.out.println((char) cha);
}
fileReader.close();
System.out.println("========================");
FileReader fileReader1 = new FileReader("day12_exercise\\aaa.txt");
//一次读取一个字符数组
int len;
char[] chars = new char[1024];
while ((len = fileReader1.read(chars)) != -1){
String s = new String(chars, 0, len);
System.out.println(s);
}
fileReader1.close();
}
}
BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入。
BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取。
构造方法:
方法名 | 说明 |
---|---|
BufferedWriter(Writer out) | 创建字符缓冲输出流对象 |
BufferedReader(Reader in) | 创建字符缓冲输入流对象 |
特有方法介绍:
BufferedWriter:void newLine() 写一行行分隔符,行分隔符字符串由系统属性定义(换行)
BufferedReader:String readLine() 读一行文字。 结果包含一行的内容,不包括任何行终止字符如果流的结尾已经到达,则为返回null
案例:使用字符缓冲流读取文件中的数据,排序后再次写到本地文件
import java.io.*;
import java.util.Arrays;
public class Demo02 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(
new FileReader("day12_exercise\\bbb.txt"));
//读取一行数据
String line = br.readLine();
String[] strArr = line.split(" ");
int[] intArr = new int[strArr.length];
for (int i = 0; i < strArr.length; i++) {
intArr[i] = Integer.parseInt(strArr[i]);
}
//排序
Arrays.sort(intArr);
//重新写回本地文件
BufferedWriter bw = new BufferedWriter(
new FileWriter("day12_exercise\\bbb.txt"));
for (int i = 0; i < intArr.length; i++) {
bw.write(intArr[i]+" ");
}
bw.flush();
bw.close();
br.close();
}
}
构造方法:
方法名 | 说明 |
---|---|
InputStreamReader(InputStream in) | 使用默认字符编码创建InputStreamReader对象 |
InputStreamReader(InputStream in,String chatset) | 使用指定的字符编码创建InputStreamReader对象 |
OutputStreamWriter(OutputStream out) | 使用默认字符编码创建OutputStreamWriter对象 |
OutputStreamWriter(OutputStream out,String charset) | 使用指定的字符编码创建OutputStreamWriter对象 |
import java.io.*;
import java.nio.charset.Charset;
public class Demo {
public static void main(String[] args) throws IOException {
//文件是什么码表,就指定一样的码表去读取
//字节输入流对象作为参数传入转换流对象
FileInputStream fis = new FileInputStream("day12_exercise\\dddcopy.txt");
InputStreamReader isr = new InputStreamReader(fis, "utf-8");
int ch;
while ((ch = isr.read()) != -1) {
System.out.println((char) ch);
}
isr.close();
//使用转换流,指定码表向文件写数据
//字节输出流对象作为参数传入装换流
FileOutputStream fos = new FileOutputStream("day12_exercise\\dddcopy.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
osw.write("秋水共长天一色");
osw.close();
//JDK11之后字符流推出了一个新的构造方法,可以指定码表
FileReader fileReader = new FileReader(
"day12_exercise\\dddcopy.txt",
Charset.forName("utf-8"));
int c;
while ((c = fileReader.read()) != -1) {
System.out.println((char) c);
}
fileReader.close();
}
}
对象操作流可以把对象以字节的形式写到本地文件,直接打开文件是读不懂的,需要再次用对象操作流将文件读到内存中。
User类:
import java.io.Serializable;
//如果想要一个类能够被序列化,必须实现接口Serializable
//Serializable是一个标记性接口,没有任何抽象方法
public class User implements Serializable {
//自定义序列号
private static final long serialVersionUID = 5586850569152704422L;
private String name;
private transient String password;
public User(String name, String password) {
this.name = name;
this.password = password;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
public User() {
}
}
序列化和反序列化:
import java.io.*;
public class Demo01 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
User user = new User("王勃", "twgx");
//反序列化user对象
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("day12_exercise\\ccc.txt"));
User o = (User)ois.readObject();
System.out.println(o);
ois.close();
}
//序列化user对象
private static void writeObject(User user) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("day12_exercise\\ccc.txt"));
oos.writeObject(user);
oos.close();
}
}
若不希望某个成员变量被序列化,可以在变量前加一个瞬态关键字 transient
案例:创建多个学生类对象写到文件中,再次读取到内存中
public class Demo{
/**
* read():
* 读取到文件末尾返回值是 -1
* readLine():
* 读取到文件的末尾返回值 null
* readObject():
* 读取到文件的末尾 直接抛出异常
* 如果要序列化的对象有多个,不建议直接将多个对象序列化到文件中,因为反序列化时容易出异常
* 建议: 将要序列化的多个对象存储到集合中,然后将集合序列化到文件中
*/
public static void main(String[] args) throws Exception {
// 序列化
//1.创建序列化流对象
ObjectOutputStream oos = new ObjectOutputStream(new
FileOutputStream("myCode\\oos.txt"));
ArrayList arrayList = new ArrayList<>();
//2.创建多个学生对象
Student s = new Student("佟丽娅",30);
Student s01 = new Student("佟丽娅",30);
//3.将学生对象添加到集合中
arrayList.add(s);
arrayList.add(s01);
//4.将集合对象序列化到文件中
oos.writeObject(arrayList);
oos.close();
// 反序列化
//5.创建反序列化流对象
ObjectInputStream ois = new ObjectInputStream(new
FileInputStream("myCode\\oos.txt"));
//6.将文件中的对象数据,读取到内存中
Object obj = ois.readObject();
ArrayList arrayList = (ArrayList)obj;
ois.close();
for (Student s : arrayList) {
System.out.println(s.getName() + "," + s.getAge());
}
}
}
Properties作为Map集合的特有方法:
方法名 | 说明 |
---|---|
Object setProperty(String key, String value) | 设置集合的键和值,都是String类型,底层调用 Hashtable方法 put |
String getProperty(String key) | 使用此属性列表中指定的键搜索属性 |
Set |
从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串 |
Properties 和IO流结合的方法:
方法名 | 说明 |
---|---|
void load(Reader reader) | 从字符输入流读取属性列表(键和元素对) |
void store(Writer writer, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流 |
将properties文件中的键值对,存到properties集合
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Properties;
public class Demo01 {
public static void main(String[] args) throws IOException {
Properties prop = new Properties();
FileReader fr = new FileReader(
"day12_exercise\\prop.properties", Charset.forName("utf-8"));
prop.load(fr);
fr.close();
System.out.println(prop);
}
}
将properties集合中的键值对,存到本地配置文件
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class Demo02 {
public static void main(String[] args) throws IOException {
Properties prop = new Properties();
FileWriter fileWriter = new FileWriter("day12_exercise\\prop.properties");
prop.put("张三","123456");
prop.put("李四","123456");
//"abc为写入文件中的注释"
prop.store(fileWriter, "abc");
fileWriter.close();
}
}
如有错误欢迎留言评论,及时更正。2021年6月11日,羽露风