`

java文件流学习实验

    博客分类:
  • JAVA
阅读更多

 

老是有人问JAVA IO的性能问题,我按照老的IO最基本的FileInputStream做了几个实验,自己记录下,实验代码都在附件包里。

 

以下是实验结果和总结

 

 

Test07一个字节一个字节的读取消耗时间(毫秒):74969

Test08按照一个byte[1024]==1k读取消耗时间(毫秒):110

 

Test10按照buffered(缺省size=512)后的fileinputstream的一个字节一个字节读取消耗时间(毫秒):1360

Test11按照buffered(缺省size=512)后的byte[1024]==1k读取消耗时间(毫秒):47

Test12按照buffered(size=1024)后的byte[1024]==1k读取消耗时间(毫秒):110

 

问题:本来预计Test12比Test11快一倍的,怎么刚好相反了????????

 

解答:因为原以为buffer的缺省size=512,所以有如下的预计,后来查看源码发现BufferedInputStream 类private static int defaultBufferSize = 8192;

 

所以

Test10按照buffered(缺省size=8192)后的fileinputstream的一个字节一个字节读取消耗时间(毫秒):1360

Test11按照buffered(缺省size=8192)后的byte[1024]==1k读取消耗时间(毫秒):46

Test12按照buffered(size=1024)后的byte[1024]==1k读取消耗时间(毫秒):109

 

可以看出Test12和Test08没有区别了,因为这个时候Test12的buffered就失去意义了

而且Test11的buffered虽然是读取块大小的8倍,但是最终的结果并没有提高八倍的速度,因为虽然和系统底层IO的交互

次数提高了8倍(BufferedInputStream 的buffer的作用),但是read的大小还是byte[1024]==1k,也就是说在BufferedInputStream 的buffer

里读的次数和Test08的读取次数一样,但唯一区别是Test11是从BufferedInputStream 的buffer里读的,读的是内存,

而Test08是从文件读的,读的是系统底层IO,所以速度肯定会有提高,但不是提高8倍,

 

如果想让Test11比Test08快8倍的话,理论上(还有些别的因素的性能消耗)只需要将Test11的读取块设置为byte[8192]==8k即可,而这样也和将Test08的size直接设置为8192就没什么区别了

这是修改后的结果

Test11按照buffered(缺省size=8192)后的byte[8192]==8k读取消耗时间(毫秒):31

Test08按照一个byte[8192]==8k读取消耗时间(毫秒):31

果然效果一样,但都没有110/8的速度。

显然缓冲再往下大下去,瓶颈就不在缓冲上了

 

由此也可以看出其实如果你用了缺省的BufferedInputStream(没有修改它的size,缺省为8k),和直接用FileInputStream.read(byte[8192])是没有区别的。

你如果用了缺省的BufferedInputStream(没有修改它的size,缺省为8k),再在这个基础上用BufferedInputStream.read(byte[sizeeeee]),当这个sizeeeee比8192

小的话也没有什么意思了,还不如直接用FileInputStream.read(byte[8192]),不加BufferedInputStream包装了。

 

那么如果用BufferedInputStream包装FileInputStream并且采用了read(byte[sizeeee])时,BufferedInputStream的

buffer<=sizeeee时随意调整buffer大小,效果均和buffer=sizeeee时一样,

因为

//需要读的字节数比BufferedInputStream设置的大,那么每次都会将BufferedInputStream里不能提供的还是需要直接读文件,而此时BufferedInputStream顺道更新自己的buffer为新的.

//读取顺序为file===>BufferedInputStream的buffer===>read(byte[sizeeeee]);

见Test12示例

 

也就是说如果你用缺省的BufferedInputStream,然后你用了read(byte[sizeeee])并将sizeeee设置为>8192时,再怎么网上加都和sizeeee=8192是没区别的,当然在sizeeee<=8192的

范围内调整sizeeee大小还是有意义的.

 

 

关于FileReader的就不再做测试了

 

 

注意Test09是用来测试中文用按照字节读取的乱码问题的,如果非要按照字节读中文或是写中文的话需要自己转码

 

 

后记:关于buffer在java io中的原理

因为单纯的java的read和write没调一次就需要和系统底层IO交互一次,那么我们就想能在一次交互的过程中尽量读取或是写入最大的内容,那么就减少了交互次数,

从而大大提高了性能。

 

 

 

 

下面部分内容来自CSDN博客http://blog.csdn.net/redv/archive/2005/03/31/334697.aspx中的一段

 

影响Java IO性能最主要的原因之一在于大量地使用单字符IO操作,即用InputStream.read()和Reader.read()方法每次读取一个字符。 Java的单字符IO操作继承自C语言。在C语言中,单字符IO操作是一种常见的操作,比如重复地调用getc()读取一个文件。C语言单字符IO操作的效率很高,因为getc()和putc()函数以宏的形式实现,且支持带缓冲的文件访问,因此这两个函数只需要几个时钟周期就可以执行完毕。在Java 中,情况完全不同:对于每一个字符,不仅要有一次或者多次方法调用,而且更重要的是,如果不使用任何类型的缓冲,要获得一个字符就要有一次系统调用。虽然一个依赖read()的Java程序可能在表现、功能上和C程序一样,但两者在性能上不能相提并论。幸而,Java提供了几种简单的办法帮助我们获得更好的IO性能。 

 

缓冲可以用以下两种方式之一实现:使用标准的BufferedReader和BufferedInputStream类,或者使用块读取方法一次读取一大块数据。前者快速简单,能够有效地改进性能,且只需少量地增加代码,出错的机会也较少。后者也即自己编写代码,复杂性略有提高——当然也说不上困难,但它能够获得更好的效果。 

 


分享到:
评论

相关推荐

    实验9 Java输入输出流.doc

    通过这个实验,学习者可以深入理解流的概念,学会如何选择合适的流进行文件操作,并掌握性能优化的方法。对于Java入门者来说,这是一个非常实用和基础的技能,对于后续的开发工作有着重要影响。

    JAVA输入输出流实验报告

    Java中的输入输出流是程序与外部数据交互的重要方式,它允许我们读取和写入数据到各种来源,如键盘、文件、网络等。在Java中,输入输出流分为两大类:字节流(Byte Stream)和字符流(Character Stream)。本次实验...

    JAVA 哈工大JAVA实验 文件切割合并处理

    此外,实验可能还会涉及到文件流的缓冲区优化,提高文件操作的效率。 在文件处理过程中,性能优化也是一个重要的话题。例如,使用缓冲区可以减少磁盘I/O次数,提高读写速度;使用多线程可以并发处理多个子文件,...

    Java实验教程 实验报告 有项目工程文件

    《Java实验教程 实验报告 有项目工程文件》 这篇实验教程主要针对Java编程语言,旨在帮助学习者通过实践操作深化对Java的理解。Java是一种广泛应用于互联网开发、企业级应用和移动开发的强大编程语言,其面向对象的...

    java的io流文件读写

    对于初学者来说,理解和掌握Java IO流的使用是学习Java编程的基础,也是进阶到更复杂系统开发的关键一步。 Java的IO流主要分为两大类:字节流(Byte Stream)和字符流(Character Stream)。字节流处理的是8位的...

    实验3 输入输出流的实验.doc

    在实验中,我们学习了文件流和对象的串行化。我们使用对象输出流将对象写入到文件中,并使用对象输入流读取文件中的对象。 9. JavaFx 实现图形用户界面 在实验中,我们使用 JavaFx 实现了图形用户界面,使得用户...

    东北大学JAVA 面向对象实验全部实验代码1到6

    9. 文件与流:Java I/O流允许程序进行输入输出操作,包括读取文件、写入文件等。实验可能有读取或保存实验数据至文件的需求。 10. 复杂数据结构:实验可能涉及到数组、链表、树等数据结构的实现,以解决特定问题,...

    东北大学JAVA实验一及实验二代码与实验报告.zip

    在Java中,可以使用`FileReader`, `BufferedReader`等类读取文件,`FileWriter`, `BufferedWriter`等类写入文件,确保正确处理文件流以防止数据丢失。 7. **逻辑判断**:"客户密码总是错误的问题.png"可能涉及到...

    JAVA实验报告 举重成绩单

    在这个JAVA实验报告中,我们关注的是如何通过编程处理文本文件,特别是涉及到文件的读写操作。...通过这个实验,学生不仅可以理解JAVA文件读写的基本原理,还能锻炼字符串处理技巧和错误处理能力。

    java实验答案及实验报告书

    5. **文件I/O操作**:Java提供了丰富的API进行文件读写,实验可能要求实现文件的创建、读取、修改和删除,或者进行更复杂的文件流操作。 6. **多线程**:Java对多线程支持良好,实验可能会让学生编写并发程序,理解...

    java 用户登录 文件流

    ### Java用户登录与文件流操作知识点解析 #### 一、概览 在给出的代码片段中,主要涉及到了几个核心的Java概念和技术点,包括文件流操作、接口和多态的应用,以及简单的用户输入和验证逻辑。这些技术点通常被用于...

    java程序设计实验报告

    通过本次实验,学生不仅可以掌握Java开发环境的配置,还能了解Java程序的基本结构,包括类的定义、主方法的写法,以及如何使用标准输出流进行信息输出。这些基础知识对于进一步学习Java编程至关重要。

    Java小实验:文件读取加密保存

    通过这个小实验,Java初学者不仅可以熟悉基本的文件操作,还能学习到加密和解密的概念,对于理解信息安全和数据保护有重要意义。实验过程中,建议逐步调试和测试每个步骤,确保文件读取、加密、保存的正确性。同时,...

    流密码 java实现

    在这个实验中,你会学习到如何在Java中使用位操作和I/O流来实现一个简单的流密码系统。实际应用中,流密码的安全性取决于密钥生成器的复杂性和密钥的长度,因此在设计时需要确保足够的安全性。同时,也要注意防止...

    吉林大学《Java程序设计》实验(所有)

    5. **输入/输出流**:I/O流用于读写文件、网络通信等,学生会学习如何使用FileInputStream、FileOutputStream以及BufferedReader、PrintWriter等类。 6. **多线程**:Java支持并发编程,学生将学习如何创建和管理...

    java实验(包含文件、多线程等)

    这个"java实验"的压缩包显然提供了学习和实践Java基础及高级特性的资源,特别是关于文件操作、多线程以及图形用户界面(GUI)和网络编程。 1. **文件操作**: 在Java中,我们可以使用`java.io`包来处理文件和流。...

    java实验报告---期末必备!不看后悔!

    通过学习Java,学生可以掌握面向对象的基本概念,例如封装、继承和多态,以及如何使用不同的数据类型、数组、文件流、图形用户界面(GUI)、网络编程和数据库操作。 实验一主要关注Java运行环境的安装。实验者需要...

    中南大学Java实验报告四

    输入/输出(IO)流是Java处理数据输入和输出的关键模块,涵盖了文件读写、网络通信等多种场景。学生可能需要实现读取本地文件、写入数据到文件,或者进行简单的网络通信,例如TCP或UDP连接。 如果实验报告涉及多...

    java 输入输出流实验.docx

    本次实验的主要目的是让学习者掌握字符输入流和输出流的基本用法,了解如何利用这些流来实现文件的读写操作,并能够将读取的文本数据以一种友好的形式展示给用户。 #### 五、实验步骤与代码示例 根据实验描述,我们...

Global site tag (gtag.js) - Google Analytics