Java面试题之 IO(三)

Java面试题之 IO(三)

文章目录

  • Java面试题之 IO(三)
    • 字节缓冲流
      • BufferedInputStream(字节缓冲输入流)
      • BufferedOutputStream(字节缓冲输出流)
    • 字符缓冲流
    • 打印流

文章来自Java Guide 用于学习如有侵权,立即删除

字节缓冲流

IO 操作是很消耗性能的,缓冲流将数据加载至缓冲区,一次性读取/写入多个字节,从而避免频繁的 IO 操作,提高流的传输效率。

字节缓冲流这里采用了装饰器模式来增强 InputStreamOutputStream子类对象的功能。

举个例子,我们可以通过 BufferedInputStream(字节缓冲输入流)来增强 FileInputStream 的功能。

// 新建一个 BufferedInputStream 对象
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("input.txt"));

字节流和字节缓冲流的性能差别主要体现在我们使用两者的时候都是调用 write(int b)read() 这两个一次只读取一个字节的方法的时候。由于字节缓冲流内部有缓冲区(字节数组),因此,字节缓冲流会先将读取到的字节存放在缓存区,大幅减少 IO 次数,提高读取效率。

我使用 write(int b)read() 方法,分别通过字节流和字节缓冲流复制一个 524.9 mb 的 PDF 文件耗时对比如下:

使用缓冲流复制PDF文件总耗时:15428 毫秒
使用普通字节流复制PDF文件总耗时:2555062 毫秒

两者耗时差别非常大,缓冲流耗费的时间是字节流的 1/165。

测试代码如下:

@Test
void copy_pdf_to_another_pdf_buffer_stream() {// 记录开始时间long start = System.currentTimeMillis();try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("深入理解计算机操作系统.pdf"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("深入理解计算机操作系统-副本.pdf"))) {int content;while ((content = bis.read()) != -1) {bos.write(content);}} catch (IOException e) {e.printStackTrace();}// 记录结束时间long end = System.currentTimeMillis();System.out.println("使用缓冲流复制PDF文件总耗时:" + (end - start) + " 毫秒");
}@Test
void copy_pdf_to_another_pdf_stream() {// 记录开始时间long start = System.currentTimeMillis();try (FileInputStream fis = new FileInputStream("深入理解计算机操作系统.pdf");FileOutputStream fos = new FileOutputStream("深入理解计算机操作系统-副本.pdf")) {int content;while ((content = fis.read()) != -1) {fos.write(content);}} catch (IOException e) {e.printStackTrace();}// 记录结束时间long end = System.currentTimeMillis();System.out.println("使用普通流复制PDF文件总耗时:" + (end - start) + " 毫秒");
}

如果是调用 read(byte b[])write(byte b[], int off, int len) 这两个写入一个字节数组的方法的话,只要字节数组的大小合适,两者的性能差距其实不大,基本可以忽略。

这次我们使用 read(byte b[])write(byte b[], int off, int len) 方法,分别通过字节流和字节缓冲流复制一个 524.9 mb 的 PDF 文件耗时对比如下:

使用缓冲流复制PDF文件总耗时:695 毫秒
使用普通字节流复制PDF文件总耗时:989 毫秒

两者耗时差别不是很大,缓冲流的性能要略微好一点点。

测试代码如下:

@Test
void copy_pdf_to_another_pdf_with_byte_array_buffer_stream() {// 记录开始时间long start = System.currentTimeMillis();try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("深入理解计算机操作系统.pdf"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("深入理解计算机操作系统-副本.pdf"))) {int len;byte[] bytes = new byte[4 * 1024];while ((len = bis.read(bytes)) != -1) {bos.write(bytes, 0, len);}} catch (IOException e) {e.printStackTrace();}// 记录结束时间long end = System.currentTimeMillis();System.out.println("使用缓冲流复制PDF文件总耗时:" + (end - start) + " 毫秒");
}@Test
void copy_pdf_to_another_pdf_with_byte_array_stream() {// 记录开始时间long start = System.currentTimeMillis();try (FileInputStream fis = new FileInputStream("深入理解计算机操作系统.pdf");FileOutputStream fos = new FileOutputStream("深入理解计算机操作系统-副本.pdf")) {int len;byte[] bytes = new byte[4 * 1024];while ((len = fis.read(bytes)) != -1) {fos.write(bytes, 0, len);}} catch (IOException e) {e.printStackTrace();}// 记录结束时间long end = System.currentTimeMillis();System.out.println("使用普通流复制PDF文件总耗时:" + (end - start) + " 毫秒");
}

BufferedInputStream(字节缓冲输入流)

BufferedInputStream 从源头(通常是文件)读取数据(字节信息)到内存的过程中不会一个字节一个字节的读取,而是会先将读取到的字节存放在缓存区,并从内部缓冲区中单独读取字节。这样大幅减少了 IO 次数,提高了读取效率。

BufferedInputStream 内部维护了一个缓冲区,这个缓冲区实际就是一个字节数组,通过阅读 BufferedInputStream 源码即可得到这个结论。

public
class BufferedInputStream extends FilterInputStream {// 内部缓冲区数组protected volatile byte buf[];// 缓冲区的默认大小private static int DEFAULT_BUFFER_SIZE = 8192;// 使用默认的缓冲区大小public BufferedInputStream(InputStream in) {this(in, DEFAULT_BUFFER_SIZE);}// 自定义缓冲区大小public BufferedInputStream(InputStream in, int size) {super(in);if (size <= 0) {throw new IllegalArgumentException("Buffer size <= 0");}buf = new byte[size];}
}

缓冲区的大小默认为 8192 字节,当然了,你也可以通过 BufferedInputStream(InputStream in, int size) 这个构造方法来指定缓冲区的大小。

BufferedOutputStream(字节缓冲输出流)

BufferedOutputStream 将数据(字节信息)写入到目的地(通常是文件)的过程中不会一个字节一个字节的写入,而是会先将要写入的字节存放在缓存区,并从内部缓冲区中单独写入字节。这样大幅减少了 IO 次数,提高了读取效率

try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {byte[] array = "JavaGuide".getBytes();bos.write(array);
} catch (IOException e) {e.printStackTrace();
}

类似于 BufferedInputStreamBufferedOutputStream 内部也维护了一个缓冲区,并且,这个缓存区的大小也是 8192 字节。

字符缓冲流

BufferedReader (字符缓冲输入流)和 BufferedWriter(字符缓冲输出流)类似于 BufferedInputStream(字节缓冲输入流)和BufferedOutputStream(字节缓冲输入流),内部都维护了一个字节数组作为缓冲区。不过,前者主要是用来操作字符信息。

打印流

下面这段代码大家经常使用吧?

System.out.print("Hello!");
System.out.println("Hello!");

System.out 实际是用于获取一个 PrintStream 对象,print方法实际调用的是 PrintStream 对象的 write 方法。

PrintStream 属于字节打印流,与之对应的是 PrintWriter (字符打印流)。PrintStreamOutputStream 的子类,PrintWriterWriter 的子类。

public class PrintStream extends FilterOutputStreamimplements Appendable, Closeable {
}
public class PrintWriter extends Writer {
}

大家好,我是xwhking,一名技术爱好者,目前正在全力学习 Java,前端也会一点,如果你有任何疑问请你评论,或者可以加我QQ(2837468248)说明来意!希望能够与你共同进步

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

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

相关文章

TCP/IP网络模型

大家好我是苏麟 , 今天聊聊TCP/IP四层网络模型 . 资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) 应用层 最上层的&#xff0c;也是我们能直接接触到的就是应用层&#xff08;Application Layer&#xff09;&#xff0c;我们电脑或手机使用的应用软件都…

ElasticSearch面试题整理(持续更新)

1. Elasticsearch 中的倒排索引是什么&#xff1f; Elasticsearch 使用一种称为倒排索引的结构&#xff0c;ES中的倒排索引其实就是 lucene 的倒排索引&#xff0c;区别于传统的正向索引&#xff0c;倒排索引会再存储数据时将关键词和数据进行关联&#xff0c;保存到倒排表中&…

Redis持久化策略指南,如何根据业务需求选择合适的方案

推荐一款我一直在用国内很火的AI网站&#xff0c;包含GPT3.5/4.0、文心一言、通义千问、智谱AI等多个AI模型&#xff0c;支持PC、APP、VScode插件同步使用&#xff0c;点击链接跳转->海鲸AI-自动生成代码 前言 Redis是一个被广泛使用的内存数据结构存储系统&#xff0c;它支…

1、PDManer 快速入门

文章目录 序言一、快速入门1.1 PDMan 介绍1.2 特点1.3 下载和安装 小结 序言 本人长期以来一直从事于应用软件的研发以及项目实施工作&#xff0c;经常做数据库建模&#xff08;数据表设计&#xff09;。有一款称心如意的数据库建模工具&#xff0c;自然能够事半功倍&#xff0…

JDK8新增的接口方法

第一种是默认方法&#xff1a; public interface A {//1.默认方法&#xff1a;必须使用default修饰&#xff0c;默认会被public修饰public default void test1(){System.out.println("默认方法");} } 默认方法就是实例方法&#xff0c;必须使用对象触发访问&#x…

洛谷C++简单题小练习day8—Bookshelf B

day8--Bookshelf B--1.30 习题概述 题目描述 Farmer John 最近为奶牛们的图书馆添置了一个巨大的书架&#xff0c;尽管它是如此的大&#xff0c;但它还是几乎瞬间就被各种各样的书塞满了。现在&#xff0c;只有书架的顶上还留有一点空间。 所有(1≤N≤20,000) N头奶牛都有一…

python爬虫概念及介绍

1. 什么是互联网爬虫&#xff1f; 解释 1 &#xff1a;通过一个程序&#xff0c;根据 Url ( http : // www . taobao . com ) 进行爬取网页&#xff0c;获取有用信息 解释 2&#xff1a;使用程序模拟浏览器&#xff0c;去向服务器发送请求&#xff0c;获取响应信息 2. 爬虫核…

JAVAEE初阶 网络编程(八)

IP协议 认识IP协议 在认识IP协议之前&#xff0c;我们首先要明确IP协议的工作范围或者是用途。 &#xff08;1&#xff09; 地址管理&#xff1a;使用一套地址体系&#xff0c;来描述互联网上各个设备所处的为止。 &#xff08;2&#xff09; 路由选择&#xff1a;数据包如何从…

@Test Annotation属性– enabled attribute

目录 而不使用enabled属性 现在&#xff0c;使用enabled属性 我们可以使用enabled属性来忽略类中的所有情况吗&#xff1f; Test注解有很多属性&#xff0c;enabled也是其中之一。在这篇文章中&#xff0c;我们将详细讨论enabled属性。 enabled属性有什么作用&#xff1f;当…

延伸与应用(三)婚姻与经济、运动、宗教、科技与经济

53&#xff0e;幸福婚姻的经济ABC方程式 夫以信先其妇&#xff0c;则妇以信顺其夫。上秉常以化下&#xff0c;下服常而应上&#xff0c;其不化者&#xff0c;百未有一也。 ——《傅子》&#xff0c;傅玄&#xff08;217—278&#xff09; 在现代的小家庭中&#xff0c;由于家庭…

Linux ssh 无法登录的情况记录

这篇主要记录一些工作中碰到过的&#xff0c;有一些记录意思的案例 情况一&#xff1a;库文件被改动 问题描述 发现测试环境&#xff08;Rhel6.4&#xff09;账号无法登陆&#xff0c;密码正确时无响应&#xff0c;错误时提示错误&#xff0c;控制台进入后发现有如下报错 ER…

Cesium 实战 - 加载 GeoJson 混合几何类型数据(同时包含 MultiPolygon 和 MultiLinestring),不能加载的问题

Cesium 实战 - 加载 GeoJson 混合几何类型数据(同时包含 MultiPolygon 和 MultiLinestring),不能加载的问题 复现问题完整代码:在线示例在之前的项目中,偶然遇到个气泡的问题:GeoJson 同时包含 MultiPolygon 和 MultiLinestring,并且数量比较大的时候,MultiLinestring …

Linux实验记录:远程控制服务

前言&#xff1a; 本文是一篇关于Linux系统初学者的实验记录。 参考书籍&#xff1a;《Linux就该这么学》 实验环境&#xff1a; VmwareWorkStation 17——虚拟机软件 RedHatEnterpriseLinux[RHEL]8——红帽操作系统 备注&#xff1a; SSH&#xff08;Secure Shell&…

安卓11修改HDMI自适应分辨率

客户需要hdmi自适应屏幕分辨率&#xff0c;没发现有相关的指令&#xff0c;我发现设置中有个hdmi的Auto选项&#xff0c;于是就试试选中这个选项&#xff0c;试下了可以自适应&#xff0c;于是就找到相关代码&#xff0c;在开机完成后执行这个代码&#xff0c;基本满足需求&…

数据中心IP代理是什么?有何优缺点?海外代理IP全解

海外代理IP中&#xff0c;数据中心代理IP是很热门的选择。这些代理服务器为用户分配不属于 ISP&#xff08;互联网服务提供商&#xff09;且来自第三方云服务提供商的 IP 地址&#xff0c;是分配给位于数据中心的服务器的 IP 地址&#xff0c;通常由托管和云公司拥有。 这些 I…

热仿真中稳态与瞬态的区别

对于热仿真&#xff0c;根据是否随时间变化&#xff0c;可分为稳态&#xff08;steady&#xff09;仿真和瞬态&#xff08;transient&#xff09;仿真两类。 从数学计算的角度&#xff0c;所谓稳态是指物理量不随时间变化的定常过程&#xff0c;即计算域中所有物理量均满足关系…

vue前端页面时间显示问题解决方法

解决方法&#xff0c; <template slot-scope"scope"><span>{{ parseTime(scope.row.boxClosingOnlineTime, {y}-{m}-{d} {h}:{i}:{s}) }}</span> </template> 刷新页面&#xff1a; 此外&#xff0c;使用JsonFormat(pattern "yyyy-M…

JavaEE UDP协议

JavaEE UDP协议 在之前的文章中有对UDP协议套接字的使用进行讲解&#xff0c;本文主要对UDP协议进行一些理论补充。 文章目录 JavaEE UDP协议1. 概念2. UDP协议格式2.1 数据报长度2.2 校验和/检验和2.2.1 CRC校验2.2.2 MD5算法 1. 概念 UDP&#xff0c;即User Datagram Proto…

【PyRestTest】高级使用

本节主要涉及PyRestTest的高级特征的详细使用,主要指:generators(生成器), variable binding(变量绑定), data extraction(数据提取), content validators(文本验证) 它们是如何组合在一起的? 模板和上下文 测试和基准测试可以使用变量来模板化动态配置。使用基础的…

【Java程序设计】【C00172】基于SSM的老年人健康管理系统(论文+PPT)

基于SSM的老年人健康管理系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于ssm的老年人健康管理系统 本系统分为前台、管理员以及用户3个功能模块。 前台&#xff1a;当游客打开系统的网址后&#xff0c;首先看到的就是首…