当前位置: 首页 > news >正文

Java高级重点知识点-22-缓冲流、转换流、序列化流、打印流

文章目录

  • 缓冲流
    • 字节缓冲流
    • 字符缓冲流
  • 转换流
    • InputStreamReader类
    • OutputStreamWriter类
  • 序列化
    • ObjectOutputStream类
    • ObjectInputStream类
  • 打印流

缓冲流

缓冲流,也叫高效流,是对4个基本的 FileXxx 流的增强,所以也是4个流
基本原理:
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。

字节缓冲流

构造方法

  • public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流
  • public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流。

通过读入一个程序与写出一个程序来举例缓冲流的使用方法。
首先准备一个较大的压缩包文件,放在了D:\file1\java.zip,这个路径下面。
在这里插入图片描述
使用缓冲流读写数据:

public class BufferedDemo {public static void main(String[] args) throws FileNotFoundException {// 记录开始时间long start = System.currentTimeMillis();// 创建流对象try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\file1\\java.zip"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\file2\\javaCopy.zip"));) {// 读写数据int len;byte[] bytes = new byte[8 * 1024];while ((len = bis.read(bytes)) != -1){bos.write(bytes, 0, len);}} catch (IOException e) {e.printStackTrace();}// 记录结束时间long end = System.currentTimeMillis();System.out.println("缓冲流使用数组复制时间:" + (end - start) + " 毫秒");}
}

在这里插入图片描述
使用基本流读写数据:

public class BufferedDemo {public static void main(String[] args) throws FileNotFoundException {// 记录开始时间long start = System.currentTimeMillis();// 创建流对象try (FileInputStream fis = new FileInputStream("D:\\file1\\java.zip");FileOutputStream fos = new FileOutputStream("D:\\file2\\javaCopy.zip")) {// 读写数据int b;while ((b = fis.read()) != -1){fos.write(b);}} catch (IOException e) {e.printStackTrace();}// 记录结束时间long end = System.currentTimeMillis();System.out.println("普通流复制时间:" + (end - start) + " 毫秒");}
}

在这里插入图片描述
从这里我们可以看到普通流对象读写数据与缓冲流(高效流)读取数据的差异性了,高效流通过一次读入多个数据到缓冲区,然后一次读出,减少IO操作,提高了读写效率。

字符缓冲流

在D:\file1目录下面创建一个in.txt文件。
在这里插入图片描述

构造方法

  • public BufferedReader(Reader in) :创建一个 新的缓冲输入流
  • public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。

特殊方法

  • BufferedReader: public String readLine() : 读一行文字。
  • BufferedWriter: public void newLine() : 写一行行分隔符,由系统属性定义符号。

代码示例:

public class BufferedReaderDemo {public static void main(String[] args) throws IOException {// 创建流对象BufferedReader br = new BufferedReader(new FileReader("D:\\file1\\in.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\file3\\out.txt"));// 定义字符串,保存读取的一行文字String line = null;// 循环读取,读取到最后返回nullwhile ((line = br.readLine()) != null) {bw.write(line, 0, line.length());bw.newLine();}// 释放资源bw.close();br.close();}
}

在这里插入图片描述

转换流

  1. 字符编码和字符集

将字符存储到计算机中,称为编码,反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码 。

  • 字符编码 Character Encoding : 就是一套自然语言的字符与二进制数之间的对应规则。
  • 字符集 Charset :也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。

常见的字符集:

  • ASCII字符集 :ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统
  • ISO-8859-1字符集:拉丁码表,别名Latin-1,用于显示欧洲使用的语言
  • GBxxx字符集:GB就是国标的意思,是为了显示中文而设计的一套字符集。
  • Unicode字符集 :Unicode编码系统为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。

问题引入:
准备一个D:\file\in.txt文件
在这里插入图片描述

public class ReaderDemo {public static void main(String[] args) throws IOException {FileReader fileReader = new FileReader("D:\\file1\\in.txt");int read;while ((read = fileReader.read()) != -1) {System.out.print((char)read);}fileReader.close();}
}

在这里插入图片描述
出现了中文乱码,这是因为Windows系统的默认是GBK编码,就会出现乱码。这个编码问题我们可以通过转换流来解决。

InputStreamReader类

转换流 java.io.InputStreamReader ,是Reader的子类,是从字节流到字符流的桥梁。
构造方法:

  • InputStreamReader(InputStream in) : 创建一个使用默认字符集的字符流。
  • InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流。
package demo10;import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;public class ReaderDemo2 {public static void main(String[] args) throws IOException {// 定义文件路径,文件为gbk编码String FileName = "D:\\file1\\in.txt";// 创建流对象,默认UTF8编码InputStreamReader isr = new InputStreamReader(new FileInputStream(FileName));// 创建流对象,指定GBK编码InputStreamReader isr2 = new InputStreamReader(new FileInputStream(FileName) , "GBK");// 定义变量,保存字符int read;// 使用默认编码字符流读取,乱码while ((read = isr.read()) != -1) {System.out.print((char)read);}isr.close();System.out.println();// 使用指定编码字符流读取,正常解析while ((read = isr2.read()) != -1) {System.out.print((char)read);}isr2.close();}
}

在这里插入图片描述
这里我们使用了俩种构造方法来创建我们的InputStreamReader对象,当我们指定了解码采用GBK格式来对我们的in.txt进行解码时,可以看到我们输出的字符是正常的而不是乱码。

OutputStreamWriter类

转换流 java.io.OutputStreamWriter ,是Writer的子类,是从字符流到字节流的桥梁。
构造方法:

  • OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。
  • OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流。
import java.io.*;public class TransDemo {public static void main(String[] args) throws IOException {// 1.定义文件路径String srcFile = "D:\\file1\\in.txt";String destFile = "D:\\file3\\out.txt";// 2.创建流对象// 2.1 转换输入流,指定GBK编码InputStreamReader isr = new InputStreamReader(new FileInputStream(srcFile) , "GBK");// 2.2 转换输出流,默认utf8编码OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(destFile));// 3.读写数据// 3.1 定义数组char[] cbuf = new char[1024];// 3.2 定义长度int len;// 3.3 循环读取while ((len = isr.read(cbuf))!=-1) {// 循环写出osw.write(cbuf,0,len);}// 4.释放资源osw.close();isr.close();}
}

在这里插入图片描述
转换流理解图解:
在这里插入图片描述

序列化

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据、对象的 类型和对象中存储的属性等信息。

  • 反序列化: 从文件中读取字节序列,重构对象

序列化流理解图解:
在这里插入图片描述

ObjectOutputStream类

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

序列化条件:

  • 该类必须实现 java.io.Serializable 接口, Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出 NotSerializableException 。
  • 该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用transient 关键字修饰。
import java.io.Serializable;public class Employee implements Serializable {public String name;public String address;public transient int age; // transient瞬态修饰成员,不会被序列化public void addressCheck() {System.out.println("Address check : " + name + " ‐‐ " + address);}
}

员工类实现类Serializable接口,表示该类可以进行序列化操作,该类中的age属性修饰了transient(瞬态)代表该字段不会被序列化。

如何进行序列化:
创建一个D:\file2目录。
在这里插入图片描述

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

在这里插入图片描述
我们可以看到对象已经被序列化到了指定文件之中。那么我们这么进行反序列化来检查我们是否序列化成功呢?那就要使用到ObjectInputStream类了。

ObjectInputStream类

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

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;public class DeserializeDemo {public static void main(String [] args) {Employee e = null;try {// 创建反序列化流FileInputStream fileIn = new FileInputStream("D:\\file2\\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); // hugeSystem.out.println("Address: " + e.address); // huangshiSystem.out.println("age: " + e.age); // 0}
}

在这里插入图片描述
通过控制台显示数据我们可以看到我们进行序列化的对象是正确的。
反序列化失败情况:

  • 该类的序列版本号与从流中读取的类描述符的版本号不匹配
  • 该类包含未知数据类型
  • 该类没有可访问的无参数构造方法

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);}
}

打印流

java.io.PrintStream 类,该类能够方便地打印各种数据类型的值
构造方法:

  • public PrintStream(String fileName) : 使用指定的文件名创建一个新的打印流。

改变流向:
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);
}
}
在这里插入图片描述
我们可以看到我们的数据输出的流向通过System.setOut(ps);改变了,输出到D:\file3\out.txt中了。(日志输出相似

欢迎java热爱者了解文章,作者将会持续更新中,期待各位友友的关注和收藏。。。

相关文章:

Java高级重点知识点-22-缓冲流、转换流、序列化流、打印流

文章目录 缓冲流字节缓冲流字符缓冲流 转换流InputStreamReader类OutputStreamWriter类 序列化ObjectOutputStream类ObjectInputStream类 打印流 缓冲流 缓冲流,也叫高效流,是对4个基本的 FileXxx 流的增强,所以也是4个流 基本原理: 缓冲流的…...

express民族民俗文化分享平台-计算机毕业设计源码22552

基于Vue的民族民俗文化分享平台设计与实现 摘 要 本文介绍了一种基于Vue.js前端框架和Express后端框架的民族民俗文化分享平台的设计和实现。该平台旨在通过线上方式,促进民族民俗文化的传播与分享,增强公众对多元文化的了解和认同。 平台为普通用户提供…...

Web 基础与HTTP 协议

域名的概述 (1 )域名的结构 (2 )域名结构类型 根域:指的是根服务器,要用来管理互联网的主目录,全世界只有13台。1个为 主根服务器,放置在美国。其余12 个均为辅根服务器,其中9个放置在美国;欧 洲2个&…...

C++超市外卖小程序-计算机毕业设计源码62482

摘要 随着社会生活节奏加快和消费习惯的变化,外卖服务成为人们日常生活中不可或缺的一部分。超市外卖作为新兴业态备受关注,然而传统外卖平台在推荐精准度和用户体验方面存在挑战。 本研究旨在基于协同过滤算法,结合C语言和MySQL数据库&#…...

合合信息“大模型加速器”亮相2024世界人工智能大会

文章目录 📑引言一、大模型发展的挑战数据稀缺问题 二、大模型“加速器”解决方案概述文档解析引擎的特征 三、文档解析引擎的优势3.1 高速处理能力3.2 智能理解文档结构3.3 多种数据类型支持3.4 高精度数据提取3.5 应用广泛,适应性强 四、复杂图表解析4…...

2024.07.03校招 实习 内推 面经

绿*泡*泡VX: neituijunsir 交流*裙 ,内推/实习/校招汇总表格 1、提前批 | 中国兵器工业集团第二〇二研究所 | 提前批/招/聘暨/暑期/开放日 提前批 | 中国兵器工业集团第二〇二研究所 | 提前批招聘暨暑期开放日 2、夏令营 | 2024年南网数字集团“未来…...

MySQL中的DDL语句

第一题 输入密码登录mysql,创建数据库zoo,转换到zoo数据库, mysql> create database zoo character set gbk; mysql> use zoo查看创建数据库zoo信息 mysql> show create database zoo;删除数据库zoo mysql> drop database zo…...

ENSP-防火墙小实验

实验总要求 我的拓扑图: 具体配置 1.交换机 vlan: # sysname Lswl # vlan batch 2 to 3 # 接口: [LSWl]int e 0/0/2 [LSWl-Ethernet0/0/2ldisplay this # interface Ethernet0/0/2port link-type accessport default vlan 2 # return [LsWl-Ethernet0…...

PHP微信小程序视频图文流量主变现小程序系统源码

💰微信小程序新机遇!视频图文流量主变现秘籍🔑 🚀【流量变现新风口】🚀 还在为微信小程序的庞大流量如何转化为真金白银而苦恼吗?今天,就带你揭秘“微信小程序视频图文流量主变现小程序”的神…...

PHP智慧社区小区物业管理系统小程序源码

让生活更便捷,社区更和谐✨ 🏡【开篇:智慧生活,从社区开始】🏡 在快节奏的现代生活中,寻找一份便捷与舒适成为了我们共同的追求。小区,作为我们日常生活的温馨港湾,其管理水平和服…...

手撸俄罗斯方块(五)——游戏主题

手撸俄罗斯方块(五)——游戏主题 当确定游戏载体(如控制台)后,界面将呈现出来。但是游戏的背景色、方块的颜色、方框颜色都应该支持扩展。 当前游戏也是如此,引入了 Theme 的概念,支持主题的扩…...

【测试开发】--安全渗透测试

1. 安全渗透 1.1 分类 web数据库安全web应用服务器安全(文件上传漏洞、文件包含漏洞)web客户端安全(XSS跨站攻击) 2. sql注入 2.1 sql注入介绍 sql注入在安全问题中排行榜首sql注入攻击是输入参数未经过滤,然后直…...

AMEYA360:类比半导体三款车规级新品介绍

类比半导体三款全新车规级智能驱动芯片——HD70504与HD70804四通道高边驱动、HD7004低导通电阻高边驱动以及DR8112直驱马达驱动芯片介绍,进一步扩展了其汽车智能驱动产品的深度与广度。 新品首发,诠释“芯”动未来 HD70504 & HD70804四通道高边驱动芯…...

内衣洗衣机哪个牌子好用?五大硬核宝藏内衣洗衣机推荐

在日常生活中,内衣洗衣机已成为现代家庭必备的重要家电之一。选择一款耐用、质量优秀的内衣洗衣机,不仅可以减少洗衣负担,还能提供高效的洗涤效果。然而,市场上众多内衣洗衣机品牌琳琅满目,让我们往往难以选择。那么&a…...

红酒与未来科技:传统与创新的碰撞

在岁月的长河中,红酒以其深邃的色泽、丰富的口感和不同的文化魅力,成为人类文明中的一颗璀璨明珠。而未来科技,则以其迅猛的发展速度和无限的可能性,领着人类走向一个崭新的时代。当红酒与未来科技相遇,一场传统与创新…...

php快速入门

前言 php是一门脚本语言,可以访问服务器,对数据库增删查改(后台/后端语言) 后台语言:php,java,c,c,python等等 注意:php是操作服务器,不能直接在…...

【排序 - 归并排序】

归并排序(Merge Sort)是一种高效的排序算法,基于分治(Divide and Conquer)策略。它将待排序数组分成两个较小的子数组,分别对它们进行排序,然后将排好序的子数组合并成一个整体有序的数组。归并…...

Appium元素定位(全网详细讲解)(二)

1.appium inspector(定位元素的工具)使用方法 详细介绍: 详细解释: 图标名称说明1Show Element Handles是否显示元素句柄2Select Elements选择元素定位3Tap/Swipe By Coordinates按坐标点击/滑动4Download Screenshot下载屏幕截…...

滑动窗口,最长子序列最好的选择 -> O(N)

最近在学校上短学期课程,做程序设计题,一下子回忆起了大一学数据结构与算法的日子! 这十天我会记录一些做题的心得,今天带来的是对于最长子序列长度题型的解题框架:滑动窗口 本质就是双指针算法: 通过le…...

【Python】已解决:Python安装过程中的报错问题

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确解决方法五、注意事项 已解决:Python安装过程中的报错问题 一、分析问题背景 在安装Python 3.9.6(64位)版本时,用户可能会遇到一个报错信息,提…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...