文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

从零开始学习 Java:简单易懂的入门指南之IO序列化、打印流、压缩流(三十三)

2023-10-12 10:53

关注

序列化、打印流、压缩流、工具包

1. 序列化

1.1 概述

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据对象的类型对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化对象的数据对象的类型对象中存储的数据信息,都可以用来在内存中创建对象。看图理解序列化:
在这里插入图片描述

1.2 ObjectOutputStream类

java.io.ObjectOutputStream 类,将Java对象的原始数据类型写出到文件,实现对象的持久存储。

构造方法

构造举例,代码如下:

FileOutputStream fileOut = new FileOutputStream("employee.txt");ObjectOutputStream out = new ObjectOutputStream(fileOut);

序列化操作

  1. 一个对象要想序列化,必须满足两个条件:
public class Employee implements java.io.Serializable {    public String name;    public String address;    public transient int age; // transient瞬态修饰成员,不会被序列化    public void addressCheck() {      System.out.println("Address  check : " + name + " -- " + address);    }}

写出对象方法

public class SerializeDemo{   public static void main(String [] args)   {    Employee e = new Employee();    e.name = "zhangsan";    e.address = "beiqinglu";    e.age = 20;     try {      // 创建序列化流对象          ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("employee.txt"));        // 写出对象        out.writeObject(e);        // 释放资源        out.close();        fileOut.close();        System.out.println("Serialized data is saved"); // 姓名,地址被序列化,年龄没有被序列化。        } catch(IOException i)   {            i.printStackTrace();        }   }}输出结果:Serialized data is saved

1.3 ObjectInputStream类

ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。

构造方法

反序列化操作1

如果能找到一个对象的class文件,我们可以进行反序列化操作,调用ObjectInputStream读取对象的方法:

public class DeserializeDemo {   public static void main(String [] args)   {        Employee e = null;        try {             // 创建反序列化流             FileInputStream fileIn = new FileInputStream("employee.txt");             ObjectInputStream in = new ObjectInputStream(fileIn);             // 读取一个对象             e = (Employee) in.readObject();             // 释放资源             in.close();             fileIn.close();        }catch(IOException i) {             // 捕获其他异常             i.printStackTrace();             return;        }catch(ClassNotFoundException c)  {        // 捕获类找不到异常             System.out.println("Employee class not found");             c.printStackTrace();             return;        }        // 无异常,直接打印输出        System.out.println("Name: " + e.name);// zhangsan        System.out.println("Address: " + e.address); // beiqinglu        System.out.println("age: " + e.age); // 0    }}

对于JVM可以反序列化对象,它必须是能够找到class文件的类。如果找不到该类的class文件,则抛出一个 ClassNotFoundException 异常。

反序列化操作2

另外,当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操作也会失败,抛出一个InvalidClassException异常。发生这个异常的原因如下:

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

public class Employee implements java.io.Serializable {     // 加入序列版本号     private static final long serialVersionUID = 1L;     public String name;     public String address;     // 添加新的属性 ,重新编译, 可以反序列化,该属性赋为默认值.     public int eid;      public void addressCheck() {         System.out.println("Address  check : " + name + " -- " + address);     }}

1.4 练习:序列化集合

  1. 将存有多个自定义对象的集合序列化操作,保存到list.txt文件中。
  2. 反序列化list.txt ,并遍历集合,打印对象信息。

案例分析

  1. 把若干学生对象 ,保存到集合中。
  2. 把集合序列化。
  3. 反序列化读取时,只需要读取一次,转换为集合类型。
  4. 遍历集合,可以打印所有的学生信息

案例实现

public class SerTest {public static void main(String[] args) throws Exception {// 创建 学生对象Student student = new Student("老王", "laow");Student student2 = new Student("老张", "laoz");Student student3 = new Student("老李", "laol");ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(student);arrayList.add(student2);arrayList.add(student3);// 序列化操作// serializ(arrayList);// 反序列化  ObjectInputStream ois  = new ObjectInputStream(new FileInputStream("list.txt"));// 读取对象,强转为ArrayList类型ArrayList<Student> list  = (ArrayList<Student>)ois.readObject();      for (int i = 0; i < list.size(); i++ ){          Student s = list.get(i);        System.out.println(s.getName()+"--"+ s.getPwd());      }}private static void serializ(ArrayList<Student> arrayList) throws Exception {// 创建 序列化流 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.txt"));// 写出对象oos.writeObject(arrayList);// 释放资源oos.close();}}

2. 打印流

2.1 概述

平时我们在控制台打印输出,是调用print方法和println方法完成的,这两个方法都来自于java.io.PrintStream类,该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。

2.2 PrintStream类

构造方法

构造举例,代码如下:

PrintStream ps = new PrintStream("ps.txt")

改变打印流向

System.out就是PrintStream类型的,只不过它的流向是系统规定的,打印在控制台上。不过,既然是流对象,我们就可以玩一个"小把戏",改变它的流向。

public class PrintDemo {    public static void main(String[] args) throws IOException {// 调用系统的打印流,控制台直接输出97        System.out.println(97);      // 创建打印流,指定文件的名称        PrintStream ps = new PrintStream("ps.txt");            // 设置系统的打印流流向,输出到ps.txt        System.setOut(ps);      // 调用系统的打印流,ps.txt中输出97        System.out.println(97);    }}

3. 压缩流和解压缩流

压缩流:

​ 负责压缩文件或者文件夹

解压缩流:

​ 负责把压缩包中的文件和文件夹解压出来

public class ZipStreamDemo1 {    public static void main(String[] args) throws IOException {        //1.创建一个File表示要解压的压缩包        File src = new File("D:\\aaa.zip");        //2.创建一个File表示解压的目的地        File dest = new File("D:\\");        //调用方法        unzip(src,dest);    }    //定义一个方法用来解压    public static void unzip(File src,File dest) throws IOException {        //解压的本质:把压缩包里面的每一个文件或者文件夹读取出来,按照层级拷贝到目的地当中        //创建一个解压缩流用来读取压缩包中的数据        ZipInputStream zip = new ZipInputStream(new FileInputStream(src));        //要先获取到压缩包里面的每一个zipentry对象        //表示当前在压缩包中获取到的文件或者文件夹        ZipEntry entry;        while((entry = zip.getNextEntry()) != null){            System.out.println(entry);            if(entry.isDirectory()){                //文件夹:需要在目的地dest处创建一个同样的文件夹                File file = new File(dest,entry.toString());                file.mkdirs();            }else{                //文件:需要读取到压缩包中的文件,并把他存放到目的地dest文件夹中(按照层级目录进行存放)                FileOutputStream fos = new FileOutputStream(new File(dest,entry.toString()));                int b;                while((b = zip.read()) != -1){                    //写到目的地                    fos.write(b);                }                fos.close();                //表示在压缩包中的一个文件处理完毕了。                zip.closeEntry();            }        }        zip.close();    }}
public class ZipStreamDemo2 {    public static void main(String[] args) throws IOException {                //1.创建File对象表示要压缩的文件        File src = new File("D:\\a.txt");        //2.创建File对象表示压缩包的位置        File dest = new File("D:\\");        //3.调用方法用来压缩        toZip(src,dest);    }        public static void toZip(File src,File dest) throws IOException {        //1.创建压缩流关联压缩包        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(dest,"a.zip")));        //2.创建ZipEntry对象,表示压缩包里面的每一个文件和文件夹        //参数:压缩包里面的路径        ZipEntry entry = new ZipEntry("aaa\\bbb\\a.txt");        //3.把ZipEntry对象放到压缩包当中        zos.putNextEntry(entry);        //4.把src文件中的数据写到压缩包当中        FileInputStream fis = new FileInputStream(src);        int b;        while((b = fis.read()) != -1){            zos.write(b);        }        zos.closeEntry();        zos.close();    }}
public class ZipStreamDemo3 {    public static void main(String[] args) throws IOException {                //1.创建File对象表示要压缩的文件夹        File src = new File("D:\\aaa");        //2.创建File对象表示压缩包放在哪里(压缩包的父级路径)        File destParent = src.getParentFile();//D:\\        //3.创建File对象表示压缩包的路径        File dest = new File(destParent,src.getName() + ".zip");        //4.创建压缩流关联压缩包        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest));        //5.获取src里面的每一个文件,变成ZipEntry对象,放入到压缩包当中        toZip(src,zos,src.getName());//aaa        //6.释放资源        zos.close();    }        public static void toZip(File src,ZipOutputStream zos,String name) throws IOException {        //1.进入src文件夹        File[] files = src.listFiles();        //2.遍历数组        for (File file : files) {            if(file.isFile()){                //3.判断-文件,变成ZipEntry对象,放入到压缩包当中                ZipEntry entry = new ZipEntry(name + "\\" + file.getName());//aaa\\no1\\a.txt                zos.putNextEntry(entry);                //读取文件中的数据,写到压缩包                FileInputStream fis = new FileInputStream(file);                int b;                while((b = fis.read()) != -1){                    zos.write(b);                }                fis.close();                zos.closeEntry();            }else{                //4.判断-文件夹,递归                toZip(file,zos,name + "\\" + file.getName());                //     no1            aaa   \\   no1            }        }    }}

4. 工具包(Commons-io)

介绍:

​ Commons是apache开源基金组织提供的工具包,里面有很多帮助我们提高开发效率的API

比如:

​ StringUtils 字符串工具类

​ NumberUtils 数字工具类

​ ArrayUtils 数组工具类

​ RandomUtils 随机数工具类

​ DateUtils 日期工具类

​ StopWatch 秒表工具类

​ ClassUtils 反射工具类

​ SystemUtils 系统工具类

​ MapUtils 集合工具类

​ Beanutils bean工具类

​ Commons-io io的工具类

​ 等等…

其中:Commons-io是apache开源基金组织提供的一组有关IO操作的开源工具包。

作用:提高IO流的开发效率。

使用方式:

1,新建lib文件夹

2,把第三方jar包粘贴到文件夹中

3,右键点击add as a library

代码示例:

public class CommonsIODemo1 {    public static void main(String[] args) throws IOException {                                    }}

5. 工具包(hutool)

介绍:

​ Commons是国人开发的开源工具包,里面有很多帮助我们提高开发效率的API

官网:
https://hutool.cn/
API文档:
https://apidoc.gitee.com/dromara/hutool/
中文使用文档:
https://hutool.cn/docs/#/

比如:

​ DateUtil 日期时间工具类

​ TimeInterval 计时器工具类

​ StrUtil 字符串工具类

​ HexUtil 16进制工具类

​ HashUtil Hash算法类

​ ObjectUtil 对象工具类

​ ReflectUtil 反射工具类

​ TypeUtil 泛型类型工具类

​ PageUtil 分页工具类

​ NumberUtil 数字工具类

使用方式:

1,新建lib文件夹

2,把第三方jar包粘贴到文件夹中

3,右键点击add as a library

代码示例:

public class Test1 {    public static void main(String[] args) {                         List<String> list = FileUtil.readLines("D:\\a.txt", "UTF-8");        System.out.println(list);    }}

后记
👉👉💕💕美好的一天,到此结束,下次继续努力!欲知后续,请看下回分解,写作不易,感谢大家的支持!! 🌹🌹🌹

来源地址:https://blog.csdn.net/m0_59230408/article/details/132334895

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯