本节课我学习的主要内容有:
1.如何去读写基本数据类型的数据
2.什么是对象的序列化以及反序列化
如何去读写基本数据类型的数据:
相关的类:
DataInputStream类:
初始化: DataInputStream(FileInputStream NAME);
以与机器无关的方式从输入流中读取基本数据类型数据,可以得到任意文件的数据。
DataOutputStream类:
初始化: DataOutputStream(FileOutputStream NAME);
以与机器无关的方式写出基本数据类型数据,可以写到任意后缀的文件中。
值得注意的是,他俩虽然表面上看着是处理基本数据类型,但是底层操作还是在
操作字节流。只不过有了它将字节流处理看起来不像对字节流进行操作了,所以
我们也管他们叫做装饰流。
什么是对象的序列化以及反序列化:
将内存中的对象按照字节序列转化并存储到存储介质上的过程。反序列化与其相反。
相关类:
ObjectInputStream类:
用于反序列化对象。
ObjectOutputStream类:
用于序列化对象。
要被序列化的对象必须实现Serializable接口或Externalizable(Serializable子接口)
这俩接口中的任意一个。
Serializable标记接口,里面没有任何方法,用来标记这个类课序列化。
值得注意的是实现的是Externalizable接口的话需要实现两个抽象方法:
writeExternal(ObjectOutput Name);
readExternal(ObjectInput Name);
transient关键字:
若希望某个属性不参与序列化,那么就用该关键字修饰该属性。我测试下来只对Serializable接口实现的类有用。
值得注意的是static变量也不会被序列化。
什么是SUID:
该属性的作用是保证对象在被序列化后,可以在反序列化的时候返回正确的版本。很重要。
属性声明:
private static final long serialVersionUID = 1L;
DataStreamTest01类(用来测试输入输出基本数据类型):
package LessonForIO04;
import java.io.*;
public class DataStreamTest01
{
public static void main(String[] args)
{
//文件创建
File file = new File("Test05.txt");
if (file.exists() != true)
{
try
{
file.createNewFile();
} catch (IOException e)
{
e.printStackTrace();
}
}
//File输出流
FileOutputStream fos1 = null;
try
{
fos1 = new FileOutputStream(file);
} catch (FileNotFoundException e)
{
e.printStackTrace();
}
//File输入流
FileInputStream fis1 = null;
try
{
fis1 = new FileInputStream(file);
} catch (IOException e)
{
e.printStackTrace();
}
//Data输出流
DataOutputStream dos1 = new DataOutputStream(fos1);
try
{
dos1.writeDouble(3.1415926);
dos1.writeUTF("你好世界!");
dos1.writeInt(10000);
} catch (IOException e)
{
e.printStackTrace();
}
//Data输入流
DataInputStream dis1 = new DataInputStream(fis1);
try
{
System.out.println(dis1.readDouble());
System.out.println(dis1.readUTF());
System.out.println(dis1.readInt());
} catch (IOException e)
{
e.printStackTrace();
}
//关闭流
try
{
dos1.close();
fos1.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
ObjectStreamTest01类(测试序列化和反序列化):
package LessonForIO04;
import java.io.*;
import java.util.*;
//将要被序列化的类Game01
//Serializable标记接口,里面没有任何方法,用来标记这个类课序列化。此时这个类才有被序列化的资格。
class Game01 implements Serializable
{
private static final long serialVersionUID = -8053835141849748882L;
private transient String name;
private double price;
public Game01()
{
}
public Game01(String name, double price)
{
super();
this.name = name;
this.price = price;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public double getPrice()
{
return price;
}
public void setPrice(double price)
{
this.price = price;
}
@Override
public String toString()
{
return "名称:"+this.getName()+" 价格:"+this.getPrice();
}
}
class Person implements Externalizable
{
//Externalizable接口的实现方式一定要有默认的无参构造函数~
private String name;
private int age;
public Person()
{
}
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;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
//可以选择要序列化对象中的属性。
out.writeUTF(this.getName());
out.writeInt(this.getAge());
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
//读取和输出的属性必须一样配对。
this.name = in.readUTF();
this.age = in.readInt();
}
@Override
public String toString()
{
return "名称:"+this.getName()+" 年龄:"+this.getAge();
}
}
public class ObjectStreamTest01
{
public static void main(String[] args)
{
//类初始化包
// Game01 _g01 = new Game01("MARIO",99);
Game01 _g01 = new Game01();
_g01.setName("MARIO");
_g01.setPrice(22);
Game01 _g02 = new Game01("MHW",199);
Person _p1 = new Person();
_p1.setName("zlm");
_p1.setAge(20);
ArrayList<Game01> game_list = new ArrayList<>();
game_list.add(_g01);
game_list.add(_g02);
game_list.forEach((k)->{
System.out.println(k);
});
//文件
File file = new File("D:\\workspace\\JDK8API\\Test02.txt");
if (file.exists() != true)
{
try
{
file.createNewFile();
} catch (IOException e)
{
e.printStackTrace();
}
}
//文件输入输出流
FileInputStream _fis1 = null;
FileOutputStream _fos1 = null;
//序列化输入输出流
ObjectInputStream _ois1= null;
ObjectOutputStream _oos1 = null;
try
{
_fis1 = new FileInputStream(file);
_fos1 = new FileOutputStream(file);
//写入对象
_oos1 = new ObjectOutputStream(_fos1);
_oos1.writeObject(game_list);
// _oos1.writeObject(_g01);
_oos1.writeObject(_p1);
//读出对象
_ois1 = new ObjectInputStream(_fis1);
System.out.println(_ois1.readObject());
System.out.println(_ois1.readObject());
// Game01 _g001 = (Game01)_ois1.readObject();//用反序列化的方式也可以创建一个对象。
// System.out.println("名称:"+_g001.getName()+" 价格:"+_g001.getPrice());
} catch (IOException | ClassNotFoundException e)
{
e.printStackTrace();
}
try
{
_ois1.close();
_oos1.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
本篇部分文字来源于:
咕嘟咖啡杨海滨老师 — 《java编程语言高级特性》
在这里十分感谢老师能够给我带来学习的激情。
2020.11.12
本文章是本人学习笔记,不进行任何商用所以不支持转载请理解!也请别拿去商用!
如果觉得对你有帮助那么欢迎你随时来回顾!
只为记录本人学习历程。
毕