专栏首页Apache IoTDBjava字节流入门(缓冲输出流)

java字节流入门(缓冲输出流)

在网上学习java IO流的时候,会发现在 new 一个流时各种嵌套,有的甚至嵌套了三四层,完全不知道是啥套路。之前我们介绍的都是基础流,今天介绍一个可以封装其他流的流 BufferedOutputStream(BFOS)。

之前介绍的 FileOutputStream、ByteArrayOutputStream 等都是基础流,在构造时候不需要传入其他流。但是 BFOS 的构造需要传入一个字节输出流。

基本用法

这个流的功能可以根据名字看出来,是一个缓冲输出流,可以当做一个缓冲区,将输出的字节暂时存在缓冲区里,那么当缓冲区满了之后干嘛呢?那就需要将缓冲的数据都刷出去,刷到另一个流,因此在构造的时候就需要传入一个流。

有点类似游泳池,水满了,就将水全部放掉,再灌新水。为了将水放掉,就需要给一个输出的目的地,这个目的地就是构造方法中需要传入的下游的输出流。其默认的缓冲区大小是 8KB。

注意这个过程,当写到8KB时,数据还存在 BFOS 中,只要再写一个字节,就将之前缓冲满的全部刷出去。如果缓冲区还没满就想将数据写出去,需要手动 flush。

完整示例如下,这里我们的下游流用了个内存数组流,并随时查看内存数组流的数据量。

运行结果:

0
8192
8195

之前介绍过列式存储文件格式:大数据的列式存储格式:Parquet

每一列的数据需要在内存中用一个缓冲区管理,如果文件只有一列,那就需要一个缓冲区,如果文件有多列,则需要多个缓冲区。在这里我们用单缓冲区多缓冲区来区分。之前我们的缓冲区用的是 BAOS,参考 java 字节流入门(内存数组流->文件流)。那用 BFOS 可不可以?

单缓冲区

假如我们在内存中只需要维护一个缓冲区的数据,即一个字节数组。当我们想写磁盘时,需要将 FOS 包装一层 BAOS 或 BFOS,为了防止过多小数据量的写操作,因此在内存中做个缓冲,将很多小数据量写操作转化成很少的大数据量写操作,充分利用磁盘的IO。

先比比速度,BFOS+FOS vs BAOS + FOS (内存中只维护一个 BAOS 或一个 BFOS ,并接一个文件输出流)哪种比较快?

做了个实验,将800M数据通过两种方式写到文件中:

BufferedOutputStream + FileOutputStream

ByteArrayOutputStream + FileOutputStream

结果:BFOS + FOS 胜出。

BFOS 比 BAOS 还有一个好处,那就是可以控制内存使用,不会无限制占用内存。这是在单个数据缓冲区的时候,即内存中只有一份缓冲数据。

多缓冲区

假如内存中需要维护多个缓冲区,每份缓冲区负责不同的数据,对应到列式存储中就是两列,都需要写到一个文件中,那么 BFOS+FOS 和 BAOS+FOS 这两种搭配有啥区别?

由于 BFOS 的刷文件是由缓冲区满触发的,我们用橙色和红色区分两个缓冲流。假如缓冲流的缓冲区大小为 8KB,每个缓冲流都接收了 24KB 的数据,但是数据并不是均匀来的,因此刷到文件中的顺序是不固定的,也就是每个流会随机触发 3 次 flush。图中 File 里每一小段是 8KB。两个流最多需要的内存是 16KB。

而使用 BAOS + FOS,假如需要明确将红黄两种数据分开存储,不能互相交叉,则最多需要在内存中缓存 48KB 数据,等一个流缓冲了 24KB 后再写文件。这样就可以将红黄两种数据分隔开,但是先后顺序不确定。

如果将红黄分开是功能要求,在这种场景下,就必须使用 BAOS。

总结

功能>>性能。为了满足一个场景,首先要找功能达到要求的,其次比较性能。在多份缓冲区时,如果要控制文件格式,需要用 BAOS,在单缓冲区时,可以考虑使用 BFOS,节省内存。

代码:

https://github.com/qiaojialin/Java-IO-Learning

致谢:东哥

本文分享自微信公众号 - IoTDB漫游指南(Apache-IoTDB),作者:铁头乔

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-06-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Apache IoTDB 建模方式详解

    之前写过一个 IoTDB 数据模型 的介绍 ,但是实际例子举得不多,所以部分用户对于一个实际系统如何建模还比较困惑,今天主要介绍一下建模实例。

    Apache IoTDB
  • LSM-tree 基本原理及应用

    LSM-tree 在 NoSQL 系统里非常常见,基本已经成为必选方案了。今天介绍一下 LSM-tree 的主要思想,再举一个 LevelDB 的例子。

    Apache IoTDB
  • PAX(Partition Attributes Across)

    今天分享一篇文章:《Weaving Relations for Cache Performance》,来自 2001 年 VLDB。看这篇之前需要先了解一下 N...

    Apache IoTDB
  • 干货——聊聊内存那些事(基于单片机系统)

    原文链接:https://www.cnblogs.com/dongxiaodong/p/13885381.html

    MCU起航
  • 【CSDN插件测评】效率增倍,程序猿开发必备插件

    在测评活动最后一天写这篇测评,CSDN最近推出的这个Chrome浏览器插件:简洁方便,免费去广告,一键搜索和直达,搜索效率极大提升,是一款既有颜值又有料的程序猿...

    三掌柜
  • Power Query中Buffer的用法

    缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对I/O(输入/输出)的数据做临时存储,这部分预留的内存空间叫缓冲区。

    逍遥之
  • 第10期 | ringbuff,通用FIFO环形缓冲区实现库

    本专栏由Mculover666创建,主要内容为寻找嵌入式领域内的优质开源项目,一是帮助开发者使用开源项目实现更多的功能,二是通过这些开源项目,学习大佬的代码及背...

    Mculover666
  • 第10期 | ringbuff,通用FIFO环形缓冲区实现库

    本期给大家带来的开源项目是 ringbuff ,一款通用FIFO环形缓冲区实现的开源库,作者MaJerle,目前收获 79 个 star,遵循 MIT 开源许可...

    morixinguan
  • 爬虫工程师面试题总结,带你入门Python爬虫

    IT派
  • 内存占用用手就能算出来

    因为存在一个复用的场景,比如之前已经开辟了400KB的大小用来显示图片A,现在我们需要显示300KB的图片B,而且图片A已经不需要显示了,那么可能就会将之前开辟...

    吴延宝

扫码关注云+社区

领取腾讯云代金券