这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战。
加缓存之 byte[]
前文说到,要改进 FileInputStream
的读写效率。所以,需要增加一个“袋子”。而这里就可以用,byte[]
来充当袋子的作用。
- 在 while 的前面加缓存,缓冲区的长度一定是 2 的整数幂,一般用 1024:
1 | Java复制代码byte[] buff = new byte[1024]; |
- while 里面微调:
1 | Java复制代码while ((temp = file.read(buff))!=-1){ |
首先,是 .read()
方法里多了一个缓存区参数,源码如下图:
其次,是 .write()
方法里的参数需要调整,源码如下图:
这里我试了一下,图片里的两种写法都是 ok 的,都可以跑出结果。
老师(尚学堂300集Java 后半部分换了另一个老师😭)用了一个较大的图片,然后用肉眼观察这个复制过程,控制台的红色矩形消失的时长。
我心想这样做还非得找个大图片吗?不行,我太懒了。而且,程序员当然要有理性的 量化思维 来算算,这种方式到底比前一种 好在哪里、好了多少。
所以那就让我们用高淇老师之前对比过 StringBuilder 和 StringBuffer 效率的计时方法(String 和 StringBuilder 效率对比),来进行一个简单的计时对比。
把上次的代码分别包装到:noneBuffer 函数
和 withBuffer 函数
里。然后前后记内存、计时,再相减。
上代码
1 | Java复制代码public static void main(String[] args) { |
运行结果:
我在 while
里还是保留了 打印 temp
的操作。所以从运行结果的图片也可以很明显的看出来,两次读的时候,每次的 temp 是不一样的。具体对比情况见下表:
比较对象 | noneBuffer | withBuffer |
---|---|---|
temp | 挨个字节 | 1024 一包一起 |
占用内存 | 2602560 | 0 |
占用时间 | 174 | 2 |
可以发现,有缓存区(withBuffer)的情况下比不加缓存区的效率简直完爆,占用的内存和时间都是个位数!
加缓存之 available()
前面那种方法,我们的 buffer
长度是写死的。现在,试试另一种可以相对「智能」地读到这个是什么。也就是 file.available()
,源码如下:
可以看到,返回的是一个在不堵的情况下允许一次性读取的最大长度,但是不堵的情况也有可能会变得堵,比如在网络差的情况下读大文件就会卡。
我已经迫不及待地好奇,这个和上一个技术哪家强了。在稍微更改代码之后,得到以下结果:
withAvailble 函数
的核心代码:
1 | Java复制代码file = new FileInputStream("/Users/fang/Images/题目.png"); |
下面这条语句,在计时的时候注释掉了。这句是因为我比较好奇,读出来的是什么:
带这条语句的运行结果:
发现这个值和前面 1024 的总和一样!可不是嘛,图片是一样的图片,字节的总长度当然一样啦。
下一次再试试缓冲流的威力 ~
本文转载自: 掘金