由浅到深认识Java语言(38):I/O流

news2024/9/28 15:30:05

该文章Github地址:https://github.com/AntonyCheng/java-notes

在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!

上一章:由浅到深认识Java语言(37):I/O流

44.I/O流(操作文件中的数据)

对象的序列化

对象序列化:简单来说就是用 IO 流技术把对象写入(ObjectOutputStream 类)文件,反之,从文件中读取(ObjectInputStream 类)一个对象就是对象的反序列化,==所以先要做序列化,才能做反序列化,这两个类依然是"装饰者";==

**开启对象序列化:**每一个普通类是没有序列化权限的,必须要实现 Serializable 接口以启用序列化;

**对象的序列化意义:**把对象变成一个文件,允许这个对象文件在网络上传输,可以让任何人使用;

JavaBeans

概念

JavaBeans是 Java 中一种特殊的类,可以将多个对象封装到一个对象(bean)中。特点是可序列化,提供无参构造器,提供 getter 方法和 setter 方法访问对象的属性。名称中的“Bean”是用于Java的可重用软件组件的惯用叫法。

优点
  • Bean可以控制它的属性、事件和方法是否暴露给其他程序。
  • Bean可以接收来自其他对象的事件,也可以产生事件给其他对象。
  • 有软件可用来配置Bean。
  • Bean的属性可以被序列化,以供日后重用。
规范

要成为 JavaBean 类别,则必需遵循关于命名、构造器、方法的特定规范。有了这些规范,才能有可以使用、复用、替代和连接 JavaBeans 的工具。

规范如下:

  • 变量私有化。
  • 有一个public的无参数构造函数。
  • 属性可以透过getsetis(可替代get,用在布尔型属性上)方法或遵循特定命名规则的其他方法访问。
  • 可序列化。
package player;

public class PersonBean implements java.io.Serializable {

    /**
     * name 属性(注意大小写)
     */
    private String name = null;

    private boolean deceased = false;

    /** 无参构造器 */
    public PersonBean() {
    }

    /**
     * name 属性的 Getter方法
     */
    public String getName() {
        return name;
    }

    /**
     * name 属性的Setter方法
     * @param value
     */
    public void setName(final String value) {
        name = value;
    }

    /**
     * deceased 属性的Getter方法
     * 布林值属性Getter方法的不同形式(这里使用了is而非get)
     */
    public boolean isDeceased() {
        return deceased;
    }

    /**
     * deceased 属性的Setter方法
     * @param value
     */
    public void setDeceased(final boolean value) {
        deceased = value;
    }
}

ObjectOutputStream 对象的序列化

  • 构造方法 ObjectOutputStream(OutputStream out) 传递字节输出流;
  • 方法 void writeObject(Object o) 写入对象;

示例如下:

package top.sharehome.Demo;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Demo {

    public static void main(String[] args) {
        Person p = new Person("张三",21);
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            oos = new ObjectOutputStream(fos);
            oos.writeObject(p);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (oos != null) {
                    oos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class Person implements Serializable {
    //这里需要加一串序列号,其作用后面内容有介绍;
    static final long serialVersionUID = 42L;
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        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 +
                '}';
    }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ObjectInputStream 对象的反序列化

  • 构造方法 ObjectInputStream(InputStream in) 传递字节输入流;
  • 方法 Object readObject() 读取对象,由于得到的是 Object 对象,所以读取到对象后还需要进行对象的强制转换;

示例如下:

package top.sharehome.Demo;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

public class Demo {
    public static void main(String[] args) {
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        try {
            fis = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            ois = new ObjectInputStream(fis);
            Object obj = ois.readObject();
            System.out.println(obj.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class Person implements Serializable {
    //这里需要加一串序列号,其作用后面内容有介绍;
    static final long serialVersionUID = 42L;
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        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 +
                '}';
    }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不能序列化的情况

静态属性:

类中的静态成员也成为实例实例,实例成员是属于类本身的,随着类的加载而加载,而我们创建的是对象,做的是对象的序列化,而实例成员并不属于我们所创建的对象,所以静态属性不会被序列化,写入文件的结果是数据类型的默认值;

transient 关键字修饰:

transient 关键字只有一个作用,那就是阻止变量的值被序列化写入文件中;

示例如下:

package top.sharehome.Demo;

import java.io.*;

public class Demo {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        Person p = new Person("李四",20);
        try {
            fos = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            fis = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\IO\\test.txt");
            oos = new ObjectOutputStream(fos);
            ois = new ObjectInputStream(fis);
            oos.writeObject(p);
            Object obj = ois.readObject();
            System.out.println(obj.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (oos!=null){
                    oos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class Person implements Serializable {
    //这里需要加一串序列号,其作用后面内容有介绍;
    static final long serialVersionUID = 42L;
    private String name;
    private transient int age; //将年龄防序列化

    public Person() {
    }

    public Person(String name, int age) {
        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 +
                '}';
    }
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

静态变量和此种情况的打印效果一模一样;

序列号

固定格式:

static final long serialVersionUID = 42L; //赋值部分可自行修改,即42L可修改;

当我们需要把一个类序列化时,不仅需要让这个类实现 Serializable 接口,还需要在类的成员变量中加入上述格式的序列号;

**序列号目的:**防止写入的文件被篡改,此时序列号就成了这个类的唯一标识;

下一章:由浅到深认识Java语言(39):网络编程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1550907.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前端学习——js篇】5.事件循环

详细:https://github.com/febobo/web-interview 5.事件循环 js是一种单线程语言,同一时间内只能做一件事情,为了避免单线程阻塞的方法就是事件循环。 在javascript当中,所有的任务都可以分为: 同步任务:按…

Java Swing游戏开发学习19

内容来自RyiSnow视频讲解 这一节讲的是**Entity ArrayList(Render Order Revised)**实体数组列表(渲染顺序修改)。 前言 由于NPC和player的实体碰撞区域比他们本身的大小要小,所以会造成一个bug,当前的绘制顺序是,NP…

进程的基础知识

1).进程:一个正在运行中的程序; 2).PCB:进程控制块,进程描述符(PID:进程唯一的标识符) 进程控制块是用一个结构体struct task_struct来实现; 3).进程的状态: 就绪,阻塞,运行; 时间片轮转调度; 时间片轮转调度是一种最古老,最简单,最公平且使用最广的…

一文即可帮助你认识进程和线程~

本文的重点:什么是:进程、进程调度、线程和他们之间的联系。主讲概念知识,不讲代码实现 目录 一、认识进程 1.什么是进程 2.进程的信息 3.进程调度(***) 4.进程调度的基本过程 二、线程 1.线程的引入 2.什么是线程 3.进程于线程的联…

鸿蒙开发之ArkUI组件常用组件图片和文本

ArkUI即方舟开发框架是HarmonyOS应用的UI开发提供了完整的基础设施,包括简洁的UI语法、丰富的UI功能(组件、布局、动画以及交互事件),以及实时界面预览工具等,可以支持开发者进行可视化界面开发。 开发文档地址 &…

【功能实现】新年贺卡(蓝桥)

题目分析: 想要实现一个随机抽取功能 功能拆解:题目给了数组,我们采用生成随机数的方式,随机数作为数组的索引值访问数组的值。 并返回获取到的值,将获取到的值插入到页面中。 document.addEventListener(DOMConten…

Diffusion添加噪声noise的方式有哪些?怎么向图像中添加噪声?

添加噪声的方式大致分为两种,一种是每张图像在任意timestep都加入一样的均匀噪声,另一种是按照timestep添加不同程度的噪声 一、在任意timestep都加入一样的noise batch_size 32x_start torch.rand(batch_size,3,256,256) noise torch.randn_like(x_…

【spring】@Autowired注解学习

Autowired介绍 Spring框架是Java领域中一个非常重要的企业级应用开发框架,它提供了全面的编程和配置模型,旨在帮助开发者更快速、更简单地创建应用程序。在Spring框架中,Autowired是一个非常重要的注解,它用于实现依赖注入&#…

保研线性代数机器学习基础复习1

1.什么是代数(algebra)? 为了形式化一个概念,构建出有关这个概念的符号以及操作符号的公式。 2.什么是线性代数(linear algebra)? 一项关于向量以及操作向量的公式的研究。 3.举一些向量的例子&#x…

我的编程之路:从非计算机专业到Java开发工程师的成长之路 | 学习路线 | Java | 零基础 | 学习资源 | 自学

小伙伴们好,我是「 行走的程序喵」,感谢您阅读本文,欢迎三连~ 😻 【Java基础】专栏,Java基础知识全面详解:👉点击直达 🐱 【Mybatis框架】专栏,入门到基于XML的配置、以…

C语言运算符和表达式——赋值运算符

目录 变量的定义 赋值运算符 赋值表达式 如何给变量赋值 变量的定义 声明变量的名字和类型 变量的类型决定了 *占用内存空间的大小 *数据的存储形式 *合法的表数范围 *可参与的运算种类 *变量名标识了内存中的一个存储单元 问题:未被初始化的变量的值是什么&a…

yolov8 pose keypoint解读

yolov8进行关键点检测的代码如下: from ultralytics import YOLO# Load a model model YOLO(yolov8n.pt) # pretrained YOLOv8n model# Run batched inference on a list of images results model([im1.jpg, im2.jpg]) # return a list of Results objects# Pr…

PCL拟合并绘制平面(二)

使用RANSAC拟合点云平面 1、C实现2、效果图 普通的点云平面拟合方式在一般情况下可以得到较好的平面拟合效果,但是容易出现平面拟合错误或是拟合的平面不是最优的情况。此时就需要根据自己的实际使用情况,调整平面拟合的迭代次数以及收敛条件。 使用RAN…

浏览器工作原理与实践--调用栈:为什么JavaScript代码会出现栈溢出

在上篇文章中,我们讲到了,当一段代码被执行时,JavaScript引擎先会对其进行编译,并创建执行上下文。但是并没有明确说明到底什么样的代码才算符合规范。 那么接下来我们就来明确下,哪些情况下代码才算是“一段”代码&am…

TheMoon 恶意软件短时间感染 6,000 台华硕路由器以获取代理服务

文章目录 针对华硕路由器Faceless代理服务预防措施 一种名为"TheMoon"的新变种恶意软件僵尸网络已经被发现正在侵入全球88个国家数千台过时的小型办公室与家庭办公室(SOHO)路由器以及物联网设备。 "TheMoon"与“Faceless”代理服务有关联,该服务…

46秒AI生成真人视频爆火,遭在线打假「换口型、声音」

ChatGPT狂飙160天,世界已经不是之前的样子。 新建了人工智能中文站 每天给大家更新可用的国内可用chatGPT资源 更多资源欢迎关注 是炒作还是真正的 AI 视频能力进化? AI 生成视频已经发展到这个程度了吗? 前段时间,英国王室凯特…

每天能提醒自己做事的app有哪个?

在忙碌的日常生活和工作中,我们时常面临各种任务和琐事。一旦处理不及时,很容易导致遗忘,进而给自己带来不必要的麻烦和损失。因此,拥有一款能够高效提醒我们做事的提醒app显得尤为重要。 敬业签就是这样一款实用的提醒软件。它不…

零基础10 天入门 Web3之第1天

10 天入门 Web3 Web3 是互联网的下一代,它将使人们拥有自己的数据并控制自己的在线体验。Web3 基于区块链技术,该技术为安全、透明和可信的交易提供支持。我准备做一个 10 天的学习计划,可帮助大家入门 Web3: 想要一起探讨学习的…

【氮化镓】位错对氮化镓(GaN)电子能量损失谱(EEL)的影响

本文献《Influence of dislocations on electron energy-loss spectra in gallium nitride》由C. J. Fall等人撰写,发表于2002年。研究团队通过第一性原理计算,探讨了位错对氮化镓(GaN)电子能量损失谱(EEL)…

python——修改注册表

如图:想要修改Public的值为2.2.1.1 import winreg# 定义要修改的键和新值 key_path rSOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList key_name Public new_name 2.2.1.1# 打开指定的键 # 注意此处是注册表路径拼接,此处是HKEY_LOCAL_MACH…