Java IO流(二)

1. 缓冲流

1.1 字节缓冲流概述

        当对文件或其他数据源进行频繁的读/写操作时,效率比较低,这时如果使用缓存流就能够更高效地读/写信息。

        比如,可以使用缓冲输出流来一次性批量写出若干数据减少写出次数来提高写出效率。

        如果用生活中的例子做比方,则如下图所示:

        相对于每次都直接从原罐中舀取的操作而言,可以先把物品舀取到一个容器中(相当于缓存),再使用容器去运输。

1.2 BIS 与 BOS

        BufferedInputStream和BufferedOutputStream称为字节缓存流。它们本身并不具有输入/输出流的读取与写入功能,只是在其他流上加上缓存功能提高效率,就像是把其他流包装起来一样,因此,缓存流是一种处理流。

        BufferedInputStream:字节缓存流内置一个缓存区,第一次调用read()方法时尽可能将数据源的数据读取到缓存区中,后续再用read()方法时先确定缓存区中是否有数据,若有则读取缓存区中的数据,当缓冲区中的数据用完后,再实际从数据源读取数据到缓存区中 ,这样可以减少直接读数据源的次数。

        BufferedOutputStream:通过输出流调用write()方法写入数据时,先将数据写入缓存区中,缓存区满了之后再将缓冲区中的数据一次性写入数据目的地。使用缓存字节流可以减少输入/输出操作的次数,以提高效率。

1.3 缓冲流文件复制示例

        编写代码,使用字节缓冲流实现文件复制。代码示意如下:

package api_03;import java.io.*;public class FileCopyDemo2 {public static void main(String[] args) throws IOException {// 随机选取本地一个文件即可,本例中的文件大小为112MBFileInputStream fis= new FileInputStream("D:/Development/nacos-server-2.0.3.zip");BufferedInputStream bis= new BufferedInputStream(fis); // 默认缓冲区大小 8192字节FileOutputStream fos= new FileOutputStream("D:/Development/nacos-server-2.0.3_cp.zip");BufferedOutputStream bos= new BufferedOutputStream(fos); // 默认缓冲区大小 8192字节int d = -1;long start = System.currentTimeMillis();while((d = bis.read())!=-1) {bos.write(d);}long end = System.currentTimeMillis();System.out.println("复制完毕!耗时"+(end-start)+"ms"); // 1566msbis.close();bos.close();}
}

1.4 flush 方法

        输出流缓冲流提供了flush方法:强制将当前缓冲区中已经缓存的字节一次性写出。可以提高数据写出的即时性,但同样也增加了实际写出的次数,一定程度上降低了写出效率。

        在输出流缓冲流的close方法中默认也会调用一次flush方法:保证在关流操作之前清空缓冲区,以避免缓冲区中的数据未能全部输出的情况。

        编写代码,测试 flush 方法。代码示意如下:

package api_03;import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;public class BOSFlushDemo {public static void main(String[] args) throws IOException {FileOutputStream fos= new FileOutputStream("./src/api_03/fos2.txt");BufferedOutputStream bos= new BufferedOutputStream(fos);String str = "这是我们输出的文字";byte[] data = str.getBytes("utf-8");bos.write(data);// bos.flush();System.out.println("写出完毕!");/** 缓冲流关闭前会调用一次flush方法.*/// bos.close();}
}

2. 序列化与反序列化

2.1 对象序列化概念

        对象是存在于内存中的,有时候我们需要将对象保存到硬盘上,又有时我们需要将对象传输到另一台计算机上等等这样的操作。这时我们需要将对象转换为一个字节序列,而这个过程就称为对象序列化

        相反,我们有这样一个字节序列需要将其转换为对应的对象,这个过程就称为对象的反序列化。

        如下图所示:

2.2 序列化与反序列化

        序列化是指先将内存中对象的相关信息(包括类、数字签名、对象除transient和static之外的全部属性值,以及对象的父类信息等)进行编码,再传输到数据目的地的过程。

        如果与序列化的顺序相反,就叫反序列化,将序列化的对象信息从数据源中读取出来,并重新解码组装为内存中一个完整的对象。

        如下图所示:

2.3 OIS 与 OOS

        Java中的序列化和反序列化是通过对象流来实现的,分别是ObjectInputStream和ObjectOutputStream。

        ObjectOutputStream:对对象进行序列化的输出流,其实现对象序列化的方法为:

void writeObject(Object o)

        该方法可以将给定的对象转换为一个字节序列后写出 。

        ObjectInputStream:对对象进行反序列化的输入流,其实现对象反序列化的方法为:

Object readObject(),

        该方法可以从流中读取字节并转换为对应的对象。

2.4 Serializable接口

        当使用对象流写入或读取对象时,需要保证对象是可序列化的。这是为了保证能把对象写入文件中,并且能再把对象正确地读回到程序中。一个类如果实现了Serializable接口,那么这个类创建的对象就是可序列化的对象。Java中的包装类和String类均实现了Serializable接口。

        Serializable接口中的方法对程序是不可见的,因此实现该接口的类不需要实现额外的方法,只是作为可序列化的标志。

        如果把一个序列化的对象写入ObjectInputStream中,Java虚拟机就会实现Serializable接口中的方法,将一定格式的数据(对象的序列化信息)写入目的地中。当使用ObjectInputStream从数据源中读取对象时,就会从数据源中读回对象的序列化信息,并根据对象的序列化信息创建一个对象。

2.5 transient关键字

        对象在序列化后得到的字节序列往往比较大,有时我们在对一个对象进行序列化时可以忽略某些不必要的属性,从而对序列化后得到的字节序列”瘦身”。此时,可以对不需要序列化的属性使用关键字 transient:被该关键字修饰的属性在序列化时其值将被忽略。

2.6 序列化示例

        首先,创建示例使用的Person类:包含4个属性,其中一个属性添加transient关键字修饰。代码示意如下:

package api_03;import java.io.Serializable;
import java.util.Arrays;
public class Person implements Serializable {String name;int age;String gender;// 使用 transient修饰的属性不会参与序列化transient String[] otherInfo;public Person(String name, int age, String gender, String[] otherInfo) {this.name = name;this.age = age;this.gender = gender;this.otherInfo = otherInfo;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", gender='" + gender + '\'' +", otherInfo=" + Arrays.toString(otherInfo) +'}';}
}

        main方法中添加代码,实现Person 对象的序列化。代码示意如下:

package api_03;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;public class SerializationDemo {public static void main(String[] args) throws IOException {String name = "苍老师";int age = 40;String gender = "男";String[] otherInfo = {"Java讲师","来自中国","会拍抖音"};Person p = new Person(name, age, gender, otherInfo);FileOutputStream fos= new FileOutputStream("./src/api_03/person.obj");ObjectOutputStream oos= new ObjectOutputStream(fos);/*这里流连接的操作分别为:1:先将给定对象通过对象流写出,此时对象流会将该对象转换为一组字节,这个过程称为对象序列化2:序列化后的字节再通过文件流写入了文件,即:写入磁盘中,这个过程称为数据持久化*/oos.writeObject(p);System.out.println("写出完毕!");oos.close();}
}

2.7 反序列化示例

        Main方法中添加代码,实现Person 对象的反序列化。代码示意如下:

package api_03;import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;public class DeSerializationDemo {public static void main(String[] args) throws IOException, ClassNotFoundException {FileInputStream fis= new FileInputStream("./src/api_03/person.obj");ObjectInputStream ois= new ObjectInputStream(fis);Person p = (Person)ois.readObject();// otherInfo属性值为null,因为是transient修饰的System.out.println(p);ois.close();}
}

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

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

相关文章

使用qemu调试NVME driver

参考nvme驱动相关的博客,可以使用qemu buildroot进行nvme驱动的流程debug。 一、QEMU编译 首先需要编译qemu,可以参考QEMU编译。wget下载最新版本的QEMU,编译之前,最好检查下依赖包是否安装,避免安装过程出现各种错…

Qwen-Audio:推动通用音频理解的统一大规模音频-语言模型(开源)

随着人工智能技术的不断进步,音频语言模型(Audio-Language Models)在人机交互领域变得越来越重要。然而,由于缺乏能够处理多样化音频类型和任务的预训练模型,该领域的进展受到了限制。为了克服这一挑战,研究…

【WebGL】修改阴影体形状,实现相交分析

阴影体(Shadow Volume)技术是计算机图形学中实现阴影的重要方式,除了用于可视化阴影效果外,阴影体还能实现线、面等要素的贴地、贴对象显示。在用阴影体贴地、贴对象时,大多数情况下我们都会认为阴影体是一个带有高度的…

OpenCV的图像矩(64)

返回:OpenCV系列文章目录(持续更新中......) 上一篇:OpenCV如何为等值线创建边界旋转框和椭圆(63) 下一篇 :OpenCV4.9的点多边形测试(65) Image Moments(图像矩)是 OpenCV 库中的一个功能,它可…

神经网络中常见的激活函数:理解与实践

神经网络中常见的激活函数:理解与实践 在神经网络中,激活函数是一个非常重要的组成部分,它为神经元引入了非线性特性,使得神经网络可以拟合各种复杂的函数关系。本文将介绍9种常见的激活函数,包括它们的概述、公式以及…

MATLAB 数据导入

MATLAB 数据导入(ImportData) 在MATLAB中导入数据意味着从外部文件加载数据。该importdata功能允许加载不同格式的各种数据文件。它具有以下五种形式 序号 功能说明 1 A importdata(filename) 从filename表示的文件中将数据加载到数组A中。 2 A i…

附录3-小程序常用事件

目录 1 点击事件 tap 2 文本框输入事件 input 3 状态改变事件 change 4 下拉刷新事件 onPullDownRefresh() 5 上拉触底事件 onReachBottom() 1 点击事件 tap 2 文本框输入事件 input 可以使用 e.detail.value 打印出当前文本框的值 我现在在文本框中依次输入12345&…

区块链 | IPFS 工作原理入门

🦊原文:What is the InterPlanetary File System (IPFS), and how does it work? 🦊写在前面:本文属于搬运博客,自己留存学习。 1 去中心化互联网 尽管万维网是一个全球性的网络,但在数据存储方面&#…

帕金森患者应该怎么注意生活方式?

在面对帕金森病的挑战时,科学合理地改善日常生活方式,不仅能帮助患者更好地管理病情,还能提升生活质量。今天,让我们一起探索如何通过简单的日常调整,为患有帕金森病的朋友们带来积极的变化。 饮食调整:营养…

【Mac】Photoshop 2024 for mac最新安装教程

软件介绍 Photoshop 2024是Adobe公司推出的一款图像处理软件,它支持Windows和Mac OS系统。Adobe Photoshop是业界领先的图像编辑和处理软件之一,广泛用于设计、摄影、数字绘画等领域。 Photoshop 2024的功能包括: 1.图像编辑:提…

MinIO学习(1) - 概览,安装

简介 MinIO 是一个高性能的分布式对象存储系统。 它是软件定义的,在行业标准硬件上运行,并且 100% 开源,主要许可证是 GNU AGPL v3。 MinIO 的不同之处在于它从一开始就被设计为私有/混合云对象存储的标准。 因为 MinIO 是专门为对象而构建…

【华为】华为防火墙双机热备

【华为】华为防火墙双机热备 实验需求实验拓扑配置FW5-M前骤单臂路由和VRRP划分防火墙基本区域部署HRP(华为心跳协议) FW6-B前骤单臂路由和VRRP划分防火墙基本区域部署HRP(华为心跳协议) LSW2PC NATSNAT :Easy IPDNAT&…

Linux进程管理与监控

一、相关概念 1、进程的的基本定义 在自身的虚拟地址空间运行的一个独立的程序,从操作系统的角度来看,所有在系统上运行的东西,都可以称为一个进程。 2、进程的分类 系统进程:可以执行内存资源分配和进程切换等管理工作&am…

spring boot 自定义starter示例

springboot 约定规范 Starter项目的命名规范 建议自定义的starter 以 xxx-spring-boot-starter 命名,官方的Starter一般都是以spring-boot-starter-为前缀。这样做的目的是为了避免与官方或其他第三方提供的Starter产生冲突或混淆。 Starter项目的结构规范(重要) …

CentOS/Anolis的Linux系统如何通过VNC登录远程桌面?

综述 需要在server端启动vncserver,推荐tigervnc的server 然后再本地点来启动client进行访问,访问方式是IPport(本质是传递数据包到某个ip的某个port) 然后需要防火墙开启端口 服务器上:安装和启动服务 安装服务 y…

【1小时掌握速通深度学习面试1】卷积神经网络-上

目录 1.简述卷积的基本操作,并分析其与全连接层的区别 2.在卷积神经网络中,如何计算各层的感受野大小?卷积层的输出尺寸、参数量和计算量。 3.简述分组卷积及其应用场景 4.简述空洞卷积的设计思路 5.简述转置卷积的主要思想以及应用场景 1.简述卷积…

Mac数据恢复软件快速比较:适用于Macbook的10佳恢复软件

数据丢失导致无数个人和组织每天损失大量资金。更糟糕的是,某些文件具有货币价值和情感意义,使它们不可替代,并使数据恢复成为唯一可行的选择。最好的消息是Mac用户可以从各种数据恢复程序中进行选择。为了帮助您尽可能快速、轻松地恢复丢失的…

54.HarmonyOS鸿蒙系统 App(ArkTS)tcp socket套接字网络连接

54.HarmonyOS鸿蒙系统 App(ArkTS)tcp socket套接字网络连接 import socket from ohos.net.socket; import process from ohos.process; import wifiManager from ohos.wifiManager;import common from ohos.app.ability.common;let tcp socket.constructTCPSocketInstance();…

搜索引擎的设计与实现参考论文(论文 + 源码)

【免费】搜索引擎的设计与实现.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89249705?spm1001.2014.3001.5501 搜索引擎的设计与实现 摘要: 我们处在一个大数据的时代,伴随着网络信息资源的庞大,人们越来越多地注重怎样才能…

SpringCloud——consul

SpringCloud——consul 一、consul安装与运行二、consul 实现服务注册与发现1.引入2.服务注册3.服务发现 三、consul 分布式配置1.基础配置2.动态刷新3.配置持久化 四、参考 Eureka已经停止更新了,consul是独立且和微服务功能解耦的注册中心,而不是单独作…