java IO流进阶 对象处理流, 转换流, 打印流

news2025/1/16 20:58:42

目录

一、对象处理流

        1.作用 : 

        2.序列化和反序列化 : 

        3.ObjectOutputStream : 

                1° 概述

                2° 演示

        4.ObjectInputStream : 

                1° 概述

                2° 演示

        5.关于序列化的细节 : 

        6.标准输入输出流:

二、转换流

        1.概述 : 

        2.InputStreamReader : 

        3.OutputStreamWriter : 

三、打印流

        1.PrintStream : 

        2.PrintWriter : 

四、Properties类内容补充

        1.拾枝杂谈 : 

        2.常见方法 : 

        3.代码演示 :


一、对象处理流

        1.作用 : 

        既可以保存数据的值,也可以保存数据的数据类型;使得数据被保存到文件中后,还能够从文件中恢复
        eg1 : 一个基本类型数据 int i = 5; ,对象处理流可以将i变量的值5和它的数据类型int都保存到文件中;

        eg2 : 一个引用类型数据 Cat cat = new Cat("bubble", 5, "white");,对象处理流可以将cat变量的值String-"bubble", int-5, String-"white"都保存下来,还可以记录下它的数据类型是Cat类型。

        2.序列化和反序列化 : 

        序列化——保存数据的值和数据类型到文件中

        反序列化——将文件中保存的数据(包含值和数据类型)重新恢复成数据本

        如下图所示 : 

        PS : 若想让某个类的对象支持序列化机制,必须让该类实现可序列化,即,实现以下两个接口之一 ——

        Serializable,一个标记接口(标记接口指“没有定义方法,只做了声明”的接口),如下图所示: 

        Externalizable,一个继承了Serializable类的接口,并且在接口中定义了两个抽象方法,如下图所示 : 

        Δ一般情况下,推荐继承第一个接口Serializable(不需要实现抽象方法)。 

        3.ObjectOutputStream : 

                1° 概述

        ObjectOutputStream继承自OutputStream类;它可以实现数据的序列化。ObjectOutputStream类同样使用了“修饰器模式”,即该类中有一个OutputStream的引用变量(存在于OutputStream类的静态内部类BlockDataOutputStream中),如下 : 

        通过OutputStream的带参构造可以传入一个OutputStream类的子类对象,以实现多态,如下所示 : 

        实现多态后,可以通过动态绑定机制,调用传入类型的特有方法

                2° 演示

                up以ObjectOutputStream_Demo类作为测试类,代码如下 : 

package csdn.knowledge.api_tools.iocurrent.object_current;

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

public class ObjectOutputStream_Demo {
    public static void main(String[] args) throws IOException {
        /*
            序列化之后,保存的文件格式不是纯文本。
         */
        ObjectOutputStream objectOutputStream =
                new ObjectOutputStream(new FileOutputStream("D:\\JAVA\\IDEA\\fileEX\\d1.dat"));

        //写入字符串
        objectOutputStream.writeUTF("Cyan_RA9");

        //自动装箱
        objectOutputStream.writeInt(141);
        objectOutputStream.writeDouble(233.33);
        objectOutputStream.writeChar('A');

        //序列化对象
        objectOutputStream.writeObject(new Cat("bubble", 5, "white"));

        //释放资源
        objectOutputStream.close();
    }
}

//序列化对象的必须条件————实现Serializable接口 或 Externalizable
class Cat implements Serializable {
    private String name;
    private int age;
    private String color;

    //建议添加该语句————
    //private static final long serialVersionUID = 1L;

    public Cat(String name, int age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }
}

                运行结果 : 

                非纯文本文件使用文本编辑器打开会出现乱码,但是依然可以看出一些端倪。 

        4.ObjectInputStream : 

                1° 概述

        ObjectInputStream类也继承自OutputStream类;它可以实现数据的反序列化。ObjectInputStream类同样使用了“修饰器模式”,即该类中有一个InputStream的引用变量(存在于InputStream类中的静态内部类PeekInputStream中),如下 : 

        通过ObjectInputStream的带参构造可以传入一个InputSream类的子类对象,以实现多态,如下所示 : 

        实现多态后,可以通过动态绑定机制,调用传入类型的特有方法

                2° 演示

                up以ObjectInputStream_Demo类为演示类,代码如下 : 

package csdn.knowledge.api_tools.iocurrent.object_current;

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

public class ObjectInputStream_Demo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream =
                new ObjectInputStream(new FileInputStream("D:\\JAVA\\IDEA\\fileEX\\d1.dat"));

        /*
            1.反序列化的顺序必须和序列化时的顺序一致,即读取数据和保存数据的顺序一致,
            否则会出现类型转换异常。
            2.更改源数据后,要重写保存,才能读取到最新时间的数据。
            3.必须使读取数据的类能够访问到对象的类
         */

        System.out.println(objectInputStream.readUTF());
        System.out.println(objectInputStream.readInt());
        System.out.println(objectInputStream.readDouble());
        System.out.println(objectInputStream.readChar());
        //抛出异常
        System.out.println(objectInputStream.readObject());
        /*
            PS : 若想使用子类特有的方法,需要进行类型转换。
         */
    }
}

                运行结果 : 

        5.关于序列化的细节 : 

       序列化或者反序列化的对象必须实现实现Serializable接口;并且序列化和反序列化时写入数据与读取数据的顺序必须一致

        序列化类中,建议添加serialVersionUID,可以提高版本的兼容性

        序列化对象时,默认要将里面所有属性都进行序列化,但不包括static和transient修饰的成员

        序列化对象时,要求里面的属性的类型也要实现序列化接口。(eg : String, Integer等类已实现了序列化)

        序列化具备可继承性,即如果某个类实现了序列化,默认其所有子类也实现了序列化。(eg : Number ---> Serializable)

        6.标准输入输出流:

        System.in——标准输入,System类中的一个公有静态引用常量,编译类型是InputStream类型,默认设备是键盘。如下图所示 : 

         System.out——标准输出,System类中的一个公有静态引用常量,编译类型是PrintStream类型,默认设备是显示器。如下图所示 : 

        两者的运行类型如下图所示 :

PS : Scanner sc = new Scanner(System.in); 中,"System.in"实际就是一个BufferedInputStream


二、转换流

        1.概述 : 

        若在txt文件中出现中文,并且该文件没有使用UTF-8形式编码;在使用IO流读取文件时就会出现乱码问题。

        转换流可以解决乱码问题,转换流可以将字节流转成字符流,同时指定读取文件时按照怎样的编码方式

        常见转换流有两个 —— InputStreamReader 和 OutputStreamWriter

        2.InputStreamReader : 

         InputStreamReader是Reader抽象类的一个子类,因此它本身属于字符流范畴。完成转换所调用的构造器如下,需要传入一个InputStream类的子类对象,以及一个编码类型。

        以InputStreamReader_Demo类为演示类,代码如下 : 

package csdn.knowledge.api_tools.iocurrent.transformation;

import java.io.*;
import static java.nio.charset.StandardCharsets.UTF_8;

public class InputStreamReader_Demo {
    public static void main(String[] args) throws IOException {
        InputStreamReader inputStreamReader =
                new InputStreamReader(new FileInputStream("D:\\JAVA\\IDEA\\file\\3.txt"), UTF_8);

        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String data;

        while ((data = bufferedReader.readLine()) != null) {
            System.out.println(data);
        }

        bufferedReader.close();
    }
}

        运行结果 : 

        3.OutputStreamWriter : 

        OutputStreamWriter类继承自Writer类,转换方法与InputStreamWriter同理

        以OutputStreamWriter_Demo类为演示类,代码如下 : 

package csdn.knowledge.api_tools.iocurrent.transformation;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * @author : Cyan_RA9
 * @version : 21.0
 */
public class OutputStreamWriter_Demo {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter outputStreamWriter =
                new OutputStreamWriter(new FileOutputStream("D:\\JAVA\\IDEA\\fileEX\\1.txt"), "UTF-16");

        outputStreamWriter.write("Space-X, 星舰发射!");

        outputStreamWriter.close();
    }
}

        运行效果 : 


三、打印流

        1.PrintStream : 

        PrintStream的类图如下 : 

        PS : PrintStream间接继承自OutputStream抽象类,属于字节流

        以PrintStream_Demo类为演示类,代码如下 : 

package csdn.advanced.io.print;

import java.io.IOException;
import java.io.PrintStream;

public class PrintStream_Demo {
    public static void main(String[] args) throws IOException {
        //out本身是PrintStream类型
        PrintStream printStream = System.out;

        //默认输出设备是显示屏
        printStream.println("Space-X!");
        printStream.write("YYDS".getBytes());

        //更改输出设备到文件
        System.setOut(new PrintStream("D:\\JAVA\\IDEA\\fileEX\\4.txt"));
        System.out.println("这盛世,如您所愿!");

        printStream.close();
    }
}

        运行结果 : 

        2.PrintWriter : 

        PrintWriter的类图如下 : 

        PS : PrintWriter类直接继承自Writer抽象类,属于字符流。 

        以PrintWriter_Demo类为演示类,代码如下 : 

package csdn.advanced.io.print;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class PrintWriter_Demo {
    public static void main(String[] args) throws IOException {
        //打印到控制台
        PrintWriter printWriter1 = new PrintWriter(System.out);
        //打印到文件(使用FileWriter的追加模式)
        PrintWriter printWriter2 = new PrintWriter(new FileWriter("D:\\JAVA\\IDEA\\fileEX\\4.txt", true));

        printWriter1.println("嘤嘤嘤");
        printWriter1.close();

        printWriter2.println("嘤嘤嘤嘤嘤嘤");
        printWriter2.close();
    }
}

        运行结果 : 


四、Properties类内容补充

        1.拾枝杂谈 : 

        在“Hashtable源码分析及其子类Properties讲解”一文中,已有简略地介绍过Properties类。(如何导入数据,读取数据,追加数据)

        Properties类是专门用于读取配置文件的集合类,也以键值对的形式保存数据;键值对默认为String类型。

        2.常见方法 : 

        load——加载配置文件的键值对到当前Properties类对象

        list——将数据显示到指定设备

        getProperty(key)——根据键获取值

        setProperty(key, value)——设置自定义键值对到Properties类对象

        store——将Properties类对象中的键值对信息存储到配置文件;在IDEA中,如果键值对中包含中文,会将中文对应的unicode码存储到配置文件。

        3.代码演示 : 

                以PropertiesEX类为演示类,代码如下 : 

package csdn.advanced.io.standart;

import java.io.*;
import java.util.Iterator;
import java.util.Properties;

/**
 * @author : Cyan_RA9
 * @version : 21.0
 */
public class PropertiesEX {
    public static void main(String[] args) throws IOException {
        Properties properties = new Properties();
        Reader reader =
                new BufferedReader(new FileReader("D:\\JAVA\\IDEA\\file\\demo2.properties"));
        Writer writer =
                new FileWriter("D:\\JAVA\\IDEA\\file\\demo3.properties", true);

        properties.load(reader);
        //listing properties
        properties.list(System.out);    //标准输出

        Iterator<String> iterator = properties.stringPropertyNames().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            System.out.println("key = " + key + " whilst value = " + properties.getProperty(key));
        }

        properties.setProperty("color", "cyan");
        properties.store(writer, "try it");

        reader.close();
        writer.close();
    }
}

                运行效果 : 

        System.out.println("END------------------------------------------------------------------------------");

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

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

相关文章

GB/T28181国标视频监控平台TINYGBS实现监控视频直播的详细搭建流程

TinyGBS是基于GB/T28181-2016(公共安全视频监控联网系统信息传输、交换、控制技术要求)开发的成熟的、敏捷的、产品化的视频汇聚平台&#xff0c;支持标准的监控设备的接入和管理&#xff0c;在多个应用场景中成功落地。实现实时视频调阅、设备控制(云台控制、聚焦控制、拉框放…

GeoDataFrame 应用:公园分布映射至subzone

0 问题描述 我们知道新加坡的monument分布&#xff1a;Monuments-Data.gov.sg 我们又知道新加坡的subzone信息&#xff1a; Master Plan 2019 Subzone Boundary (No Sea) - Datasets - Dataportal.asia 我们希望生成一个 dataframe&#xff0c;表示每一个subzone有几个monumen…

Django REST Framework(DRF)框架之认证Authentication与权限Permission

DRF框架之认证与权限 认证与权限认证(Authentication)权限(Permission) 认证和权限的使用创建用户用于验证配置认证与权限&#xff08;全局&#xff09;视图指定认证与权限&#xff08;局部&#xff09; 自定义权限概述创建自定义权限类使用自定义权限类 使用TokenAuthenticati…

LeetCode二叉树的相关题目

110. 平衡二叉树 方法&#xff1a;递归 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullpt…

漫谈大数据 - HiveSQL总结(一)库表操作

导语&#xff1a;针对hive各种数据库操作&#xff0c;内部表、外部表、分区表、分桶表的表属性查看修改操作以及hive数据的导入与导出详解。 hive简介&#xff1a; hive是基于Hadoop的一个数据仓库工具&#xff0c;用来进行数据提取、转化、加载&#xff0c;这是一种可以存储、…

双系统安装Windowslinux

文章目录 1.1 联想小新windows10重装1.2 宏基暗影骑士windows10重装2.1 ubuntu18.04重装1&#xff09;清理空间并制作U盘启动2&#xff09;ubuntu分区 3.1 ros安装4.1 deb包安装5.1 网络设置6.1 VSCode环境配置 1.1 联想小新windows10重装 bioss设置 ①微软官网制作u盘启动 ②…

微信小程序PHP+python+nodejs+springboot+vue 电影院订票选座系统

管理员的主要功能有&#xff1a; 1.管理员输入账户登陆后台 2.个人中心&#xff1a;管理员修改密码和账户信息 3.会员管理&#xff1a;对注册的会员信息进行删除&#xff0c;查询&#xff0c;添加&#xff0c;修改 4.电影分类管理&#xff1a;对电影的分类信息进行添加&#xf…

python+nodejs+springboot+vue 教学师生互动答疑系统

然后遵循软件常规开发流程&#xff0c;首先针对系统选取适用的语言和开发平台&#xff0c;根据需求分析制定模块并设计数据库结构&#xff0c;再根据系统总体功能模块的设计绘制系统的功能模块图&#xff0c;流程图以及E-R图。然后&#xff0c;设计框架并根据设计的框架编写代码…

浅学WebFlux--构建一个响应式的SpringBoot服务

前言 看惯了SpringMVC&#xff0c;最近在闲来之余抽空了解了一下Spring早已发布并支持的一种新web框架-WebFlux。由于这玩意的使用需要具备的基础是Reactive programming 的理解、Reactor 的基础以及熟练的java8 lambda使用。但是并不影响笔者摸着石头过河……在此做个浅学笔记…

【三十天精通Vue 3】第十二天 Vue 3 过滤器详解(已废弃)

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录 引言一、Vue 3 过滤器概述1.1 过滤器的简介1.2 过滤器的作用1.3 过…

创建Vue3.0工程

1.使用 vue-cli 创建 官方文档&#xff1a;创建一个项目 | Vue CLI (vuejs.org) ## 查看vue/cli版本&#xff0c;确保vue/cli版本在4.5.0以上 vue --version ## 安装或者升级你的vue/cli npm install -g vue/cli ## 创建 vue create vue_test ## 启动 cd vue_test npm run se…

7年时间,从功能测试到测试开发月薪30K,有志者事竟成

突破自己的技术瓶颈并不是一蹴而就&#xff0c;还是需要看清楚一些东西&#xff0c;这里也有一些经验和见解跟大家分享一下。同样是职场人士&#xff0c;我也有我的经历和故事。在工作期间&#xff0c;我有过2年加薪5次的小小“战绩”&#xff08;同期进入公司的员工&#xff0…

番外12:ADS导出到AD变为PCB文件

番外12&#xff1a;ADS导出到AD变为PCB文件并嘉立创制板 番外12&#xff1a;ADS导出到AD变为PCB文件&#xff0c;此处的示例为功率放大器&#xff01; STEP 1: 从ADS导出dxf文件 打开制作好的版图文件&#xff0c;在原有基础上打好散热孔和固定孔&#xff0c;散热孔半径0.63…

PCB阻焊桥存在的DFM(可制造性)问题,华秋一文告诉你

PCB表面的一层漆&#xff0c;称为阻焊油墨&#xff0c;也就是PCB线路板阻焊油墨。阻焊油墨是PCB线路板中非常常见、也是主要使用的油墨&#xff0c;一般90%都是绿色&#xff0c;但也有杂色油墨&#xff1a;红色、蓝色、黑色、白色、黄色等。 阻焊油墨的作用就是绝缘&#xff0…

反射:替对象执行方法

反射&#xff0c;可不只是利用Class创建对象哟&#xff0c;更重要是替对象执行方法&#xff01;关于反射创建对象&#xff0c;它可以提供一种通用的机制&#xff0c;对任意Class对象得到它的实例&#xff0c;而不需要import。 举个例子&#xff0c;Spring底层就是利用反射为我…

各种文字生成图片的AIGC模型(openAI、谷歌、stable、Midjourney等)

1 前言 AIGC&#xff0c;全名“AI generated content”&#xff0c;又称生成式AI&#xff0c;意为人工智能生成内容。例如AI文本续写&#xff0c;文字转图像的AI图、视频等。 本文主要描述文字生成图片的模型。而且目前扩散模型&#xff08;Diffusion Models&#xff09;流行…

CANoe使用记录(一):新建Canoe工程

目录 1、概述 2、新建工程 2.1、新建工程界面 2.2、查看License 2.3、添加DBC文件 2.4、测量窗口 2.5、通道用量 2.6、通道匹配 2.7、硬件通道配置 2.8、状态监控 1、概述 Canoe是德国Vector公司推出的一款总线开发设备&#xff0c;主要用于总线类的开发、仿真、测试…

【Python】【进阶篇】二十六、Python爬虫的Scrapy爬虫框架

目录 二十六、Python爬虫的Scrapy爬虫框架26.1 Scrapy下载安装26.2 创建Scrapy爬虫项目1) 创建第一个Scrapy爬虫项目 26.3 Scrapy爬虫工作流程26.4 settings配置文件 二十六、Python爬虫的Scrapy爬虫框架 Scrapy 是一个基于 Twisted 实现的异步处理爬虫框架&#xff0c;该框架…

【Java 数据结构】单链表经典面试题 (动图解析)

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

Redis问题

一、认识Redis 1. 什么是 Redis&#xff1f; Redis 是一种基于内存的数据库&#xff0c;对数据的读写操作都是在内存中完成&#xff0c;因此读写速度非常快&#xff0c;常用于缓存&#xff0c;消息队列、分布式锁等场景。Redis 提供了多种数据类型来支持不同的业务场景&#…