一,前言

  在前面的IO中,我们都是讲数据以字符串的形式保存。能不能将一个数组保存到文件呢,当取出数据时也是一个数组,如果能够实现那就完美了。我们都知道比较通用的有JSON格式的序列化,那java中也有这样的API。那就是JAVA的序列化。

二,Properties集合

  2.1 简介

  Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。

  特点:

    1、Hashtable的子类,map集合中的方法都可以用。

    2、该集合没有泛型。键值都是字符串。

    3、它是一个可以持久化的属性集。键值可以存储到集合中,也可以存储到持久化的设备(硬盘、U盘、光盘)上。键值的来源也可以是持久化的设备。

    4、有和流技术相结合的方法。

    

/*
*
* Properties集合,它是唯一一个能与IO流交互的集合
*
* 需求:向Properties集合中添加元素,并遍历
*
* 方法:
* public Object setProperty(String key, String value)调用 Hashtable 的方法 put。
* public Set<String> stringPropertyNames()返回此属性列表中的键集,
* public String getProperty(String key)用指定的键在此属性列表中搜索属性
*/
public class PropertiesDemo01 {
public static void main(String[] args) {
//创建集合对象
Properties prop = new Properties();
//添加元素到集合
//prop.put(key, value);
prop.setProperty("周迅", "张学友");
prop.setProperty("李小璐", "贾乃亮");
prop.setProperty("杨幂", "刘恺威"); //System.out.println(prop);//测试的使用 {key=value, key2=value2}
//遍历集合
Set<String> keys = prop.stringPropertyNames();
for (String key : keys) {
//通过键 找值
//prop.get(key)
String value = prop.getProperty(key);
System.out.println(key+"==" +value);
}
}
}

  2.2 将集合中的内容存储到文件

    需求:使用Properties集合,完成把集合内容存储到IO流所对应文件中的操作

    分析:

      1,创建Properties集合

      2,添加元素到集合

      3,创建流

      4,把集合中的数据存储到流所对应的文件中

        stroe(Writer,comments)

        store(OutputStream,commonts)

        把集合中的数据,保存到指定的流所对应的文件中,参数commonts代表对描述信息

      5,关闭流

public class PropertiesDemo02 {
public static void main(String[] args) throws IOException {
//1,创建Properties集合
Properties prop = new Properties();
//2,添加元素到集合
prop.setProperty("周迅", "张学友");
prop.setProperty("李小璐", "贾乃亮");
prop.setProperty("杨幂", "刘恺威"); //3,创建流
FileWriter out = new FileWriter("prop.properties");
//4,把集合中的数据存储到流所对应的文件中
prop.store(out, "save data");
//5,关闭流
out.close();
}
}

  2.3 读取文件中的数据,并保存到集合

    需求:从属性集文件prop.properties 中取出数据,保存到集合中

    分析:

    1,创建集合

    2,创建流对象

    3,把流所对应文件中的数据 读取到集合中

      load(InputStream)  把指定流所对应的文件中的数据,读取出来,保存到Propertie集合中

      load(Reader)

    4,关闭流

    5,显示集合中的数据

public class PropertiesDemo03 {
public static void main(String[] args) throws IOException {
//1,创建集合
Properties prop = new Properties();
//2,创建流对象
FileInputStream in = new FileInputStream("prop.properties");
//FileReader in = new FileReader("prop.properties");
//3,把流所对应文件中的数据 读取到集合中
prop.load(in);
//4,关闭流
in.close();
//5,显示集合中的数据
System.out.println(prop); }
}

三,序列化流与序列化流

  用于从流中读取对象的

    操作流 ObjectInputStream    称为 反序列化流

  用于向流中写入对象的

    操作流 ObjectOutputStream   称为 序列化流

  特点:用于操作对象。可以将对象写入到文件中,也可以从文件中读取对象。

  3.1 对象序列化流ObjectOutputStream

  ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。

  注意:只能将支持 java.io.Serializable 接口的对象写入流中

    

    如下示例:

public class ObjectStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
/*
* 将一个对象存储到持久化(硬盘)的设备上。
*/
writeObj();//对象的序列化。
}
public static void writeObj() throws IOException {
//1,明确存储对象的文件。
FileOutputStream fos = new FileOutputStream("tempfile\\obj.object");
//2,给操作文件对象加入写入对象功能。
ObjectOutputStream oos = new ObjectOutputStream(fos);
//3,调用了写入对象的方法。
oos.writeObject(new Person("wangcai",20));
//关闭资源。
oos.close();
}
}

   Person类:

public class Person implements Serializable {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
} 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 String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}

  3.2 对象反序列化流ObjectInputStream

  ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。支持 java.io.Serializable接口的对象才能从流读取。

  如下示例:

public class ObjectStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
readObj();//对象的反序列化。
}
public static void readObj() throws IOException, ClassNotFoundException { //1,定义流对象关联存储了对象文件。
FileInputStream fis = new FileInputStream("tempfile\\obj.object"); //2,建立用于读取对象的功能对象。
ObjectInputStream ois = new ObjectInputStream(fis); Person obj = (Person)ois.readObject(); System.out.println(obj.toString()); }
}

  3.3 序列化接口

    当一个对象要能被序列化,这个对象所属的类必须实现Serializable接口。否则会发生异常NotSerializableException异常。

    同时当反序列化对象时,如果对象所属的class文件在序列化之后进行的修改,那么进行反序列化也会发生异常InvalidClassException。发生这个异常的原因如下:

      该类的序列版本号与从流中读取的类描述符的版本号不匹配

      该类包含未知数据类型

      该类没有可访问的无参数构造方法

    Serializable标记接口。该接口给需要序列化的类,提供了一个序列版本号。serialVersionUID. 该版本号的目的在于验证序列化的对象和对应类是否版本匹配。

   如下代码:

public class Person implements Serializable {
//给类显示声明一个序列版本号。
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Person() {
super(); }
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
} 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 String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}

  3.4 瞬态关键字transient

    当一个类的对象需要被序列化时,某些属性不需要被序列化,这时不需要序列化的属性可以使用关键字transient修饰。只要被transient修饰了,序列化时这个属性就不会琲序列化了。

    同时静态修饰也不会被序列化,因为序列化是把对象数据进行持久化存储,而静态的属于类加载时的数据,不会被序列化。

  如下代码:

public class Person implements Serializable {
/*
* 给类显示声明一个序列版本号。
*/
private static final long serialVersionUID = 1L;
private static String name;
private transient/*瞬态*/ int age; public Person() {
super(); } public Person(String name, int age) {
super();
this.name = name;
this.age = age;
} 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 String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}

四,打印流

  4.1 打印流的概述

    打印流添加输出数据的功能,使它们能够方便地打印各种数据值表示形式.

    打印流根据流的分类:

      字节打印流 PrintStream

      字符打印流 PrintWriter

      方法:

        void print(String str): 输出任意类型的数据,

        void println(String str): 输出任意类型的数据,自动写入换行操作

    如下代码:

 /*
* 需求:把指定的数据,写入到printFile.txt文件中
*
* 分析:
* 1,创建流
* 2,写数据
* 3,关闭流
*/
public class PrintWriterDemo {
public static void main(String[] args) throws IOException {
//创建流
//PrintWriter out = new PrintWriter(new FileWriter("printFile.txt"));
PrintWriter out = new PrintWriter("printFile.txt");
//2,写数据
for (int i=0; i<5; i++) {
out.println("helloWorld");
}
//3,关闭流
out.close();
}
}

  4.2 打印流完成数据刷新

  可以通过构造方法,完成文件数据的自动刷新功能

   构造方法:

     开启文件自动刷新写入功能

    public PrintWriter(OutputStream out, boolean autoFlush)

    public PrintWriter(Writer out, boolean autoFlush)

  代码演示:

 /*
* 分析:
* 1,创建流
* 2,写数据
*/
public class PrintWriterDemo2 {
public static void main(String[] args) throws IOException {
//创建流
PrintWriter out = new PrintWriter(new FileWriter("printFile.txt"), true);
//2,写数据
for (int i=0; i<5; i++) {
out.println("helloWorld");
}
//3,关闭流
out.close();
}
}

五,总结

字节流

  字节输入流 InputStream

    FileInputStream 操作文件的字节输入流

    BufferedInputStream高效的字节输入流

    ObjectInputStream 反序列化流

  字节输出流 OutputStram

    FileOutputStream 操作文件的字节输出流

    BufferedOutputStream 高效的字节输出流

    ObjectOuputStream 序列化流

    PrintStream 字节打印流

字符流

  字符输入流 Reader

    FileReader 操作文件的字符输入流

    BufferedReader 高效的字符输入流

    InputStreamReader 输入操作的转换流(把字节流封装成字符流)

  字符输出流 Writer

    FileWriter 操作文件的字符输出流

    BufferedWriter 高效的字符输出流

    OutputStreamWriter 输出操作的转换流(把字节流封装成字符流)

    PrintWriter 字符打印流

方法:

  读数据方法:

    read() 一次读一个字节或字符的方法

    read(byte[]  char[]) 一次读一个数组数据的方法

    readLine() 一次读一行字符串的方法(BufferedReader类特有方法)

    readObject() 从流中读取对象(ObjectInputStream特有方法)

  写数据方法:

    write(int) 一次写一个字节或字符到文件中

    write(byte[] char[]) 一次写一个数组数据到文件中

    write(String) 一次写一个字符串内容到文件中

    writeObject(Object ) 写对象到流中(ObjectOutputStream类特有方法)

    newLine() 写一个换行符号(BufferedWriter类特有方法)

向文件中写入数据的过程

  1,创建输出流对象

  2,写数据到文件

  3,关闭输出流

从文件中读数据的过程

  1, 创建输入流对象

  2, 从文件中读数据

  3, 关闭输入流

文件复制的过程

  1, 创建输入流(数据源)

  2, 创建输出流(目的地)

  3, 从输入流中读数据

  4, 通过输出流,把数据写入目的地

  5, 关闭流

File类

  方法

    获取文件名称 getName()

    获取文件绝对路径 getAbsolutePath()

    获取文件大小 length()

    获取当前文件夹中所有File对象  File[] listFiles()

    判断是否为文件 isFile()

    判断是否为文件夹 isDirectory()

    创建文件夹 mkdir()  mkdirs()

    创建文件 createNewFile()

Properties:Map集合的一种,它是Hashtable集合的子集合,它键与值都是String类型,它是唯一能与IO流结合使用的集合

  方法

    load( InputStream in ) 从流所对应的文件中,读数据到集合中

    load( Reader in ) 从流所对应的文件中,读数据到集合中

    store( OutputStream out , String message ) 把集合中的数据,写入到流所对应的文件中

    store( Writer out , String message) 把集合中的数据,写入到流所对应的文件

实现文件内容的自动追加

  构造方法

    FileOutputStream(File file, boolean append)

    FileOutputStream(String fileName, boolean append)

    FileWriter(File, boolean append)

    FileWriter(String fileName, boolean append)

实现文件内容的自动刷新

  构造方法

    PrintStream(OutputStream out, boolean autoFlush)

    PrintWriter(OutputStream out, boolean autoFlush)

    PrintWriter(Writer out, boolean autoFlush)

Java 基础 IO流之序列化的更多相关文章

  1. Java基础-IO流对象之序列化(ObjectOutputStream)与反序列化(ObjectInputStream)

    Java基础-IO流对象之序列化(ObjectOutputStream)与反序列化(ObjectInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.对象的序 ...

  2. Java基础IO流(二)字节流小案例

    JAVA基础IO流(一)https://www.cnblogs.com/deepSleeping/p/9693601.html ①读取指定文件内容,按照16进制输出到控制台 其中,Integer.to ...

  3. Java基础-IO流对象之压缩流(ZipOutputStream)与解压缩流(ZipInputStream)

    Java基础-IO流对象之压缩流(ZipOutputStream)与解压缩流(ZipInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 之前我已经分享过很多的J ...

  4. Java基础-IO流对象之随机访问文件(RandomAccessFile)

    Java基础-IO流对象之随机访问文件(RandomAccessFile) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.RandomAccessFile简介 此类的实例支持对 ...

  5. Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream)

    Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.内存 ...

  6. Java基础-IO流对象之数据流(DataOutputStream与DataInputStream)

    Java基础-IO流对象之数据流(DataOutputStream与DataInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据流特点 操作基本数据类型 ...

  7. Java基础-IO流对象之打印流(PrintStream与PrintWriter)

    Java基础-IO流对象之打印流(PrintStream与PrintWriter) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.打印流的特性 打印对象有两个,即字节打印流(P ...

  8. java基础-IO流对象之Properties集合

    java基础-IO流对象之Properties集合 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Properties集合的特点 Properties类表示了一个持久的属性集. ...

  9. Java基础-IO流对象之字符缓冲流(BufferedWriter与BufferedReader)

    Java基础-IO流对象之字符缓冲流(BufferedWriter与BufferedReader) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.字符缓冲流 字符缓冲流根据流的 ...

随机推荐

  1. Python学习笔记二

    ---恢复内容开始--- 一. python几种数据类型的比较. 从以下几个方面比较: 1. 是否可变. 不可变类型:变量的值可以发生变化,id也变了,相当于创建了一个新的对象,所以一修改值,id就变 ...

  2. Spring设置定时任务时,关于执行时间的规则设置

    been需要在xml文件中进行配置 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE bean ...

  3. tensorflow激励函数-【老鱼学tensorflow】

    当我们回到家,如果家里有异样,我们能够很快就会发现家中的异样,那是因为这些异常的摆设在我们的大脑中会产生较强的脑电波. 当我们听到某个单词,我们大脑中跟这个单词相关的神经元会异常兴奋,而同这个单词无关 ...

  4. gitLib操作笔录《一》:创建分支,切换分支,提交分支到远程,以及基本代码clone与更新提交到远程操作指令

    git 操作经验注:master表示的是主线,origin 表示远程源 创建分支:git checkout -b < branch_name >或 < master >切换分支 ...

  5. 微信小程序--家庭记账本开发--06

    重要部分学习——记账簿 本次项目开发的目的主要是记账本的开发,最初自己想法简单,把家里的纸质记账簿变成手机上的记账簿.最终自己程序可以实现的功能可以记录每天的账目信息,并形成叠加效果,并按1.2.3… ...

  6. 下面为初学者分享一下SQL 数据库学习资料

    一.基础 1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备份 ...

  7. yum clear all无反应

    卸载重装yum 操作系统版本:centos7 [root@linux-node3 ~]# uname -r 3.10.0-514.el7.x86_64 一.将现有的yum源卸载 [root@linux ...

  8. Pycharm 2018.2.1最新版破解到2099年图解教程

    我破解后的效果图 安装我就不说了 工具解压在随便一个目录(文末有下载百度网盘链接)在 Pycharm安装目录的\bin目录下找到 pycharm.exe.vmoptions 和 pycharm64.e ...

  9. django——web框架简介

    1.web应用 Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件. 应用程序有两种模式C/S.B/S.C/S是客户 ...

  10. js以键值对的方式获取URL的参数

    在前端日常的开发中,大多数时候我们只需用js获取到url中的参数即可,这个实现起来也很方便如: function getQueryString(value) { const reg = new Reg ...