• IO流【Java对象的序列化和反序列化、File类在IO中的作用、装饰器模式构建IO流体系、Apache commons-io工具包的使用】(四)-全面详解(学习总结---从入门到深化)


     

    目录

     Java对象的序列化和反序列化

    将对象反序列化到内存中

    File类在IO中的作用

    装饰器模式构建IO流体系

     Apache commons-io工具包的使用


     

     Java对象的序列化和反序列化

     序列化和反序列化是什么

    当两个进程远程通信时,彼此可以发送各种类型的数据。 无论是何 种类型的数据,都会以二进制序列的形式在网络上传送。比如,我 们可以通过http协议发送字符串信息;我们也可以在网络上直接发 送Java对象。发送方需要把这个Java对象转换为字节序列,才能在 网络上传送;接收方则需要把字节序列再恢复为Java对象才能正常 读取。 把Java对象转换为字节序列的过程称为对象的序列化。把字节序列 恢复为Java对象的过程称为对象的反序列化。

     序列化涉及的类和接口

    ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写 到一个目标输出流中。

    ObjectInputStream代表对象输入流,它的readObject()方法从一个 源输入流中读取字节序列,再把它们反序列化为一个对象,并将其 返回。 只有实现了Serializable接口的类的对象才能被序列化。 Serializable接口是一个空接口,只起到标记作用。

     将对象序列化到文件

     ObjectOutputStream可以将一个内存中的Java对象通过序列化的方 式写入到磁盘的文件中。被序列化的对象必须要实现Serializable序 列化接口,否则会抛出异常。

     创建对象

    1. public class Users implements Serializable {
    2. private int userid;
    3. private String username;
    4. private String userage;
    5. public Users(int userid, String username, String userage) {
    6. this.userid = userid;
    7. this.username = username;
    8. this.userage = userage;
    9. }
    10. public Users() { }
    11. public int getUserid() {
    12. return userid;
    13. }
    14. public void setUserid(int userid) {
    15. this.userid = userid;
    16. }
    17. public String getUsername() {
    18. return username;
    19. }
    20. public void setUsername(String username)
    21. {
    22. this.username = username;
    23. }
    24. public String getUserage() {
    25. return userage;
    26. }
    27. public void setUserage(String userage) {
    28. this.userage = userage;
    29. }
    30. @Override
    31. public String toString() {
    32. return "Users{" +
    33. "userid=" + userid +
    34. ", username='" + username + '\'' +
    35. ", userage='" + userage + '\'' +
    36. '}';
    37. }

    序列化对象

    1. public class TestObjectOutputStream {
    2. public static void main(String[] args) {
    3. //创建对象输出字节流与文件输出字节流对象
    4. try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:/data3"))){
    5. //创建Users对象
    6. Users users = new Users(1,"Oldlu","18");
    7. //将对象序列化到文件中
    8. oos.writeObject(users);
    9. //刷新
    10. oos.flush();
    11. }catch(IOException e){
    12. e.printStackTrace();
    13. }
    14. }
    15. }

     

    将对象反序列化到内存中

    1. public class TestObjectInputStream {
    2. public static void main(String[] args) {
    3. //创建对象输入字节流与文件字节输入流对象
    4. try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/data3")))
    5. {
    6. //将对象反序列化到内存中
    7. Users users = (Users) ois.readObject();
    8. System.out.println(users);
    9. }catch(Exception e){
    10. e.printStackTrace();
    11. }
    12. }
    13. }

     

    File类在IO中的作用

     当以文件作为数据源或目标时,除了可以使用字符串作为文件以及 位置的指定以外,我们也可以使用File类指定。

    1. public class TestFile {
    2. public static void main(String[] args) {
    3. //创建字符缓冲流与文件字符输入流对象
    4. try(BufferedReader br = new BufferedReader(new FileReader(new File("d:/sxt.txt")));
    5. //创建字符输出流对象
    6. PrintWriter pw = new PrintWriter(new File("d:/sxt8.txt"))){
    7. //操作流
    8. String temp = "";
    9. int i=1;
    10. while((temp = br.readLine()) != null){
    11. pw.println(i+","+temp);
    12. i++;
    13. }
    14. pw.flush();
    15. }catch(IOException e){
    16. e.printStackTrace();
    17. }
    18. }
    19. }

    装饰器模式构建IO流体系

    装饰器模式简介

    装饰器模式是GOF23种设计模式中较为常用的一种模式。它可以实 现对原有类的包装和装饰,使新的类具有更强的功能。

     装饰器模式

    1. class Iphone {
    2. private String name;
    3. public Iphone(String name) {
    4. this.name = name;
    5. }
    6. public void show() {
    7. System.out.println("我是" + name + ",可以在屏幕上显示");
    8. }
    9. }
    10. class TouyingPhone {
    11. public Iphone phone;
    12. public TouyingPhone(Iphone p) {
    13. this.phone = p;
    14. }
    15. // 功能更强的方法
    16. public void show() {
    17. phone.show();
    18. System.out.println("还可以投影,在墙壁上显示");
    19. }
    20. }
    21. public class TestDecoration {
    22. public static void main(String[] args) {
    23. Iphone phone = new Iphone("iphone30");
    24. phone.show();
    25. System.out.println("===============装饰后");
    26. TouyingPhone typhone = newTouyingPhone(phone);
    27. typhone.show();
    28. }
    29. }

    IO流体系中的装饰器模式

    IO流体系中大量使用了装饰器模式,让流具有更强的功能、更强的 灵活性。比如:

    1. FileInputStream fis = new FileInputStream(src);
    2. BufferedInputStream bis = new BufferedInputStream(fis);

     显然BufferedInputStream装饰了原有的FileInputStream,让普通 的FileInputStream也具备了缓存功能,提高了效率。

     Apache commons-io工具包的使用

     Apache基金会介绍

    Apache软件基金会(也就是Apache Software Foundation,简称 为ASF),是专门为支持开源软件项目而办的一个非盈利性组织。 在它所支持的Apache项目与子项目中,所发行的软件产品都遵循 Apache许可证(Apache License)。 官方网址为: www.apache.org 。 很多著名的Java开源项目都来源于这个组织。比如:commons、 kafka、lucene、maven、shiro、struts等技术,以及大数据技术 中的:hadoop(大数据第一技术)、hbase、spark、storm、 mahout等。

     commons-io工具包

    Apache的commons-io工具包中提供了IOUtils/FileUtils,为我们 提供了更加简单、功能更加强大的文件操作和IO流操作功能。非常 值得大家学习和使用。

     下载与添加commons-io包

      下载地址 https://commons.apache.org/proper/commons-io/download_i o.cgi

      添加jar包

     

     

     FileUtils类中常用方法的介绍

    打开FileUtils的api文档,我们抽出一些工作中比较常用的方法,进 行总结和讲解。总结如下:

     读取文件内容,并输出到控制台上(只需一行代码!)

    1. import java.io.File;
    2. import org.apache.commons.io.FileUtils;
    3. public class TestUtils1 {
    4. public static void main(String[] args) throws Exception {
    5. String content = FileUtils.readFileToString(new File("d:/a.txt"), "gbk");
    6. System.out.println(content);
    7. }
    8. }

    使用FileUtils工具类实现目录拷贝

    我们可以使用FileUtils完成目录拷贝,在拷贝过程中可以通过文件过 滤器(FileFilter)选择拷贝内容。

    1. import java.io.File;
    2. import java.io.FileFilter;
    3. import org.apache.commons.io.FileUtils;
    4. public class TestFileUtilsDemo2 {
    5. public static void main(String[] args) throws Exception {
    6. FileUtils.copyDirectory(new File("d:/aaa"), new File("d:/bbb"), new FileFilter() {
    7. @Override
    8. public boolean accept(File pathname) {// 使用FileFilter过滤目录和以html结尾的文件
    9. if (pathname.isDirectory() || pathname.getName().endsWith("html")) {
    10. return true;
    11. } else {
    12. return false;
    13. }
    14. }
    15. });
    16. }
    17. }

    IOUtils的妙用

    打开IOUtils的api文档,我们发现它的方法大部分都是重载的。所 以,我们理解它的方法并不是难事。因此,对于方法的用法总结如 下:

     

     我们没有必要对每个方法做测试,只是演示一下读入d:/sxt.txt文件 内容到程序中,并转成String对象,打印出来。

     IOUtils的使用

    1. import java.io.*;
    2. import org.apache.commons.io.IOUtils;
    3. public class TestIOUtilsDemo {
    4. public static void main(String[] args) throws Exception {
    5. String content = IOUtils.toString(new FileInputStream("d:/sxt.txt"),"utf-8");
    6. System.out.println(content);
    7. }
    8. }

    本章总结

    按流的方向分类:

          输入流:数据源到程序(InputStream、Reader读进来)。

          输出流:程序到目的地(OutputStream、Writer写出去)。

    按流的处理数据单元分类:

         字节流:按照字节读取数据(InputStream、 OutputStream)。

         字符流:按照字符读取数据(Reader、Writer)。

    按流的功能分类:

         节点流:可以直接从数据源或目的地读写数据。

         处理流:不直接连接到数据源或目的地,是处理流的流。通 过对其他流的处理提高程序的性能。

    IO的四个基本抽象类:InputStream、OutputStream、 Reader、Writer

    InputStream的实现类:

         FileInputStream

         BufferedInputStream

         DataInputStream

         ObjectInputStream

    OutputStream的实现类:

         FileOutputStream

         BufferedOutputStream

         DataOutputStream

         ObjectOutputStream

    Reader的实现类

         FileReader

         BufferedReader

         InputStreamReader

    Writer的实现类

         FileWriter

         BufferedWriter

         OutputStreamWriter

         PrintWriter

    把Java对象转换为字节序列的过程称为对象的序列化。

    把字节序列恢复为Java对象的过程称为对象的反序列化。

  • 相关阅读:
    Java8实战-总结42
    一台TrinityCore服务器客户端连接网速慢(未解决)
    LongAdder原理浅析
    C++ [继承]
    【LeetCode: 137. 只出现一次的数字 II | 位运算 | 哈希表】
    联想拯救者电脑数据恢复方法,适用于未备份者
    【Java】异常、线程
    NumPy 数组索引 切片
    Android中Gradle的使用
    K8S 控制器 service ingress
  • 原文地址:https://blog.csdn.net/m0_58719994/article/details/131647462