目录
编辑
转换流
利用转换流按照指定字符编码读取
利用转换流按照指定字符编码写出
将本地文件中的GBK文件。转成UTF-8
练习
序列化流
反序列化流 /对象操作输入流
序列化流/反序列化流的细节
练习
转换流
是字符流和字节流之间的桥梁
字符转换输入流:InputStreamReader
字符转换输出流:0utputStreamWriter
下面我们来看个例子👇
利用转换流按照指定字符编码读取
这是GBK文件
package convertstream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class ConvertStreamDemo1 {
public static void main(String[] args) throws IOException {
InputStreamReader isr=new InputStreamReader(new FileInputStream("..\\Myio\\a.txt"),"GBK");
//读取资源
int ch;
while((ch=isr.read())!=-1){
System.out.print((char)ch);
}
//释放资源
isr.close();
}
}
在jdk11:这种方法被淘汰了
我们用下面的替代方案
package convertstream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
public class ConvertStreamDemo1 {
public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("..\\Myio\\a.txt", Charset.forName("GBK"));
//读取资源
int ch;
while((ch=fr.read())!=-1){
System.out.print((char)ch);
}
//释放资源
fr.close();
}
}
利用转换流按照指定字符编码写出
package convertstream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class ConvertStreamDemo2 {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("..\\Myio\\d.txt"),"GBK");
//写出数据
osw.write("你好你好");
//释放资源
osw.close();
}
}
就可以查看写出的数据
下面为替代方法
package convertstream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
public class ConvertStreamDemo2 {
public static void main(String[] args) throws IOException {
FileWriter fw=new FileWriter("..\\Myio\\d.txt", Charset.forName("GBK"));
//写出数据
fw.write("你好你好");
//释放资源
fw.close();
}
}
将本地文件中的GBK文件。转成UTF-8
jdk11以前的方案👇
package convertstream;
import java.io.*;
public class ConvertStreamDemo3 {
public static void main(String[] args) throws IOException {
InputStreamReader isr=new InputStreamReader(new FileInputStream("..\\Myio\\a.txt"),"GBK");
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("..\\Myio\\d.txt"),"UTF-8");
int a;
while ((a=isr.read())!=-1){
osw.write(a);
}
//释放资源
osw.close();
isr.close();
}
}
替代方案👇
package convertstream;
import java.io.*;
import java.nio.charset.Charset;
public class ConvertStreamDemo3 {
public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("..\\Myio\\a.txt", Charset.forName("GBK"));
FileWriter fw=new FileWriter("..\\Myio\\d.txt",Charset.forName("UTF-8"));
int a;
while ((a=fr.read())!=-1){
fw.write(a);
}
//释放资源
fw.close();
fr.close();
}
}
运行结果都是一样的
练习
利用字节流读取文件中的数据,每次读一整行,面且不能出现乱码
package convertstream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class ConvertStreamDemo4 {
public static void main(String[] args) throws IOException {
InputStreamReader isr=new InputStreamReader(new FileInputStream("..\\Myio\\d.txt"));
BufferedReader br=new BufferedReader(isr);
String line;
while((line=br.readLine())!=null) {
System.out.println(line);
}
br.close();
}
}
还可以给创建对象的合并在一起👇
序列化流
序列化流/对象操作输出流
可以把Java中的对象写到本地文件中
构造方法:
public objectoutputstream(outputstream out) 把基本流包装成高级流成员方法:
public final void writeobject(object obj) 把对象序列化(写出)到文件中去
利用序列化流/对象操作输出流,把一个对象写到本地文件中👇
先写Student类
package objectstream;
public class Student {
private String name;
private Integer age;
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public Integer getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(Integer age) {
this.age = age;
}
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
}
再写测试类
package objectstream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ObjectStreamDemo1 {
public static void main(String[] args) throws IOException {
//创建学生对象
Student stu=new Student("张三",18);
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("..\\Myio\\a.txt"));
//写出数据
oos.writeObject(stu);
//释放资源
oos.close();
}
}
使用对象输出流将对象保存到文件时会出现NotserializableException异常
解决方案:需要让Javabean类实现Serializable接口
Serializable接口里面是没有抽象方法,标记型接口
一旦实现了这个接口,那么就表示当前的student类可以被序列化
修改后的Student类:
package objectstream;
import java.io.Serializable;
public class Student implements Serializable {
private String name;
private Integer age;
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public Integer getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(Integer age) {
this.age = age;
}
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
}
反序列化流 /对象操作输入流
可以把序列化到本地文件中的对象,读取到程序中来
构造方法
public objectInputstream(Inputstream out) 把基本流变成高级流成员方法
public object readobject() 把序列化到本地文件中的对象,读取到程序中来
package objectstream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ObjectStreamDemo2 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("..\\Myio\\a.txt"));
Object o = ois.readObject();
System.out.println(o);
ois.close();
}
}
序列化流/反序列化流的细节
先序列化流将数据写到本地文件当中
如果现在在Student类里加上👇
这个时候运行反序列化流就会出现报错
文件中的版本号,跟lavabean的版本号不匹配
我们可以复制Serializable,在setting里粘贴进去
勾选标红线的两个,再Apply->OK
再回到Student中,贯标放到Student上Alt+回车,让idea帮我们添加
这个时候再执行一遍上述的添加address的操作,也就不会报错
如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
重新写一下Student类
package objectstream;
import java.io.Serial;
import java.io.Serializable;
public class Student implements Serializable {
@Serial
private static final long serialVersionUID = 348569226864978244L;
private String name;
private Integer age;
private String address;
public Student() {
}
public Student( String name, Integer age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public Integer getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(Integer age) {
this.age = age;
}
/**
* 获取
* @return address
*/
public String getAddress() {
return address;
}
/**
* 设置
* @param address
*/
public void setAddress(String address) {
this.address = address;
}
public String toString() {
return "Student{" + serialVersionUID + ", name = " + name + ", age = " + age + ", address = " + address + "}";
}
}
这个时候我不想序列化address
可以在前面加上transient关键字
这个时候执行一遍
address不参与序列化
- 使用序列化流将对象写到文件时,需要让Javabean类实现Serializable接口,否则,会出现NotSerializableException异常
- 序列化流写到文件中的数据是不能修改的,一旦修改就无法再次读回来了
- 序列化对象后,修改了Javabean类,再次反序列化,会不会有问题?会出问题,会抛出InvalidclassException异常解决方案:给Javabean类添加serialVersionUID(列号、版本号)
- 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
解决方案:给该成员变量加transient关键字修饰该关键字标记的成员变量不参与序列化过程
练习
将多个自定义对象序列化到文件中。但是对象的个数不确定,该如何操作呢?
Student类
package convertstream;
import java.io.Serial;
import java.io.Serializable;
public class Student implements Serializable {
@Serial
private static final long serialVersionUID = 3771817918770415923L;
private String name;
private Integer age;
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public Integer getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(Integer age) {
this.age = age;
}
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
}
序列化流:
package convertstream;
import java.io.*;
import java.util.ArrayList;
public class ConvertStreamTest1 {
public static void main(String[] args) throws IOException {
Student s1=new Student("张三",18);
Student s2=new Student("李四",20);
Student s3=new Student("王五",19);
ArrayList<Student>list=new ArrayList<>();
list.add(s1);
list.add(s2);
list.add(s3);
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("..\\Myio\\a.txt"));
oos.writeObject(list);
oos.close();
}
}
反序列化流
package convertstream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
public class ConvertStreamTest2 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("..\\Myio\\a.txt"));
ArrayList<Student>list = (ArrayList<Student>)ois.readObject();
for (Student student : list) {
System.out.println(student);
}
ois.close();
}
}
转换流与序列化流就说到这里啦
努力遇见更好的自己!!!