IO流BufferedOutputStream 一定比 FileOutputStream 快吗?

网友投稿 949 2022-05-28

FilteOutputStream

不带缓冲的操作(FilteOutputStream类和FilteInputStream类),每读一个字节就要写入一个字节,由于涉及磁盘的IO操作相比内存的操作要慢很多,所以在读写的字节比较少的情况下,效率比较低;

FileOutputStream fileOutputStream = new FileOutputStream("D:\1.txt");

1

BufferedOutputStream

BufferedOutputStream是带缓冲区的输出流,不管是BufferedOutputStream还是BufferedInputStream里面都自带了默认缓冲区,大小是8192Byte,也就是8KB ,能够减少访问磁盘的次数,提高文件读取性能;它们都用到了装饰器模式;将FilteOutputStream装到里面,所以 BufferedOutputStream 是 依赖FilteOutputStream 的;

当传输的文件特别大的时候,BufferInputStream的优点就体现出来了 ,带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小(默认8KB)的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多!这就是两者的区别

BufferedOutputStream什么时候会往磁盘中写数据呢?

第①种:缓存区满了,写出去!

第②种:flush()方法被调用,写出去!

第③种:close()方法被调用,写出去!因为,close()方法被调用的时候,会先调用flush()方法。

如何设置缓冲区大小

看到了吗?构造方法的第二个参数就是缓冲区大小,可以自己自行配置,默认的size就是8192,也就是8kb。

// out 写 BufferedOutputStream in = new BufferedOutputStream(new FileOutputStream("D:\out.txt"),8192); // in 读 BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("D:\in.txt"),8192);

1

2

3

4

5

区别

通过介绍,对它们内部的也就有了一定的了解了;

BufferedOutputStream 真的比 FileOutputStream 快吗?

为了验证这个这个问题,我们需要做两轮测试,通过写入少量的数据和大量数据对比一下它们之间的速度如何;

第一轮测试 :每次只写一个字节

这一轮测试里面,会延时5秒,在这5秒内不停地往文件中写入一个字节的数据;我们看看5秒后BufferedOutputStream 和 FileOutputStream 能写多少数据,代码如下,(

注意:这2个测试方法用到了一个共享变量run,所以测试时一定要分开运行,千万不可以一起运行这个2个测试方法,否则测试数据不准确

volatile boolean run = true; // 标志位 // 不带缓冲区 每次只写一个字节 @Test public void fileWriteOneByte() throws IOException { FileOutputStream fileOutputStream = new FileOutputStream("D:\FileOutputStream_one.txt"); // 延时5秒 fiveSeconds(); while (run){ // 每次写一个字节 fileOutputStream.write(1); } fileOutputStream.flush(); fileOutputStream.close(); } // 带缓冲区-->每次只写一个字节 @Test public void bufferWriteOneByte() throws IOException { FileOutputStream fileOutputStream = new FileOutputStream("D:\BufferedOutputStream_one.txt"); BufferedOutputStream bufferedInputStream = new BufferedOutputStream(fileOutputStream); // 延时5秒 fiveSeconds(); while (run){ // 每次写一个字节 bufferedInputStream.write((byte)1); } bufferedInputStream.flush(); bufferedInputStream.close(); } /** * 延时5秒 */ private void fiveSeconds(){ new Thread(new Runnable() { @Override public void run() { try { // 睡5秒 Thread.sleep(5000); // 跳出死循环 run = false; } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

IO流:BufferedOutputStream 一定比 FileOutputStream 快吗?

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

运行后,我们看看结果,显而易见,带缓冲区的BufferedOutputStream在5秒内写入了300M的数据,而不带缓冲区的FileOutputStream在5秒内只写入了1.71M的数据;这个读写速度对比,简直就是碾压型的;

第二轮测试:每次写入81920个字节(80KB)

这一次我们加大量级,当它们每次都写入81920个字节时,也就是80K,看看这2种方式在5秒内能写多少数据,写的速度会有什么变化呢?谁写的更多呢?让我们拭目以待,上代码 (

注意:这2个测试方法用到了一个共享变量run,所以测试时一定要分开运行,千万不可以一起运行这个2个测试方法,否则测试数据不准确

volatile boolean run = true; // 每次写81920个字节 @Test public void file() throws IOException { byte[] bytes = new byte[81920]; FileOutputStream fileOutputStream = new FileOutputStream("D:\\FileOutputStream_81920.txt"); // 延时5秒 fiveSeconds(); while (run){ // 每次写入 81920 个字节 fileOutputStream.write(bytes); } fileOutputStream.flush(); fileOutputStream.close(); } // 每次写81920个字节 @Test public void bufferFile() throws IOException { byte[] bytes = new byte[81920]; FileOutputStream fileOutputStream = new FileOutputStream("D:\\BufferedOutputStream_81920.txt"); BufferedOutputStream bufferedInputStream = new BufferedOutputStream(fileOutputStream,81920); // 延时5秒 fiveSeconds(); while (run){ // 每次写入 81920 个字节 bufferedInputStream.write(bytes); } bufferedInputStream.flush(); bufferedInputStream.close(); } // 延时5秒 private void fiveSeconds(){ new Thread(new Runnable() { @Override public void run() { try { // 睡5秒 Thread.sleep(5000); // 跳出死循环 run = false; } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

通过结构可以看到,带缓冲区的BufferedOutputStream在5秒内写入了将近4.5G的数据,而不带缓冲区的FileOutputStream 在5秒内写入了 6.87G的数据, FileOutputStream 反而更快了;

结论

通过以上的数据可以得出结论,谁快谁慢是根据实际情况来决定的,而不是说带了缓冲区就一定快;

每次写入的数据量小的情况下,带缓冲区的BufferedOutputStream效率更快;

每次写入的数据量比较大时,不带缓冲区的 FileOutputStream 效率更快;

所以,大家在选择的时候就需要根据实际情况来决定使用哪种IO流了,而大部分情况下,FileOutputStream 就已经足够了,只需要将写入的数据量大一点即可;

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:高可用prometheus集群方案选型分享
下一篇:关于性能测试你可能需要知道这些东西!
相关文章