论文索引
调整
JavaTMI/O性能
GlenMcCluskey
翻译:cherami
这篇文章讨论和阐明了提供JavaTMI/O性能的多种技术。大多技术围绕调整磁盘文件I/O,但是有些内容也同样适合
网络I/O和窗口输出。第一部分技术讨论底层的I/O
问题,然后讨论诸如压缩,格式化和串行化等高级I/O问题。然而这个讨论没有包含应用
设计问题,例如
搜索算法和数据结构,也没有讨论
系统级的问题,例如文件高速缓冲。
当我们讨论JavaI/O时,值得注意的是Java语言采取两种截然不同的磁盘文件结构。一个是基于字节流,另一个是字符序列。在Java语言中一个字符有两个字节表示,而不是像通常的语言如c语言那样是一个字节。因此,从一个文件读取字符时需要进行转换。这个不同在某些情况下是很重要的,就像下面的几个例子将要展示的那样。
低级I/O问题
加速I/O的基本规则
缓冲
读写文本文件
格式化的代价
随机访问
高级I/O问题
压缩
高速缓冲
分解
串行化
获取文件信息
更多信息
加速I/O的基本规则
作为这个讨论的开始,这里有几个如何加速I/O的基本规则:
避免访问磁盘
避免访问底层的操作系统
避免方法调用
避免个别的处理字节和字符
很明显这些规则不能在所有的问题上避免,因为如果能够的话就没有实际的I/O被执行。考虑下面的计算文件中的新行符('\n')的三部分范例。
方法1:read方法
第一个方法简单的使用FileInputStream的read方法:
importjava.io.*;publicclassintro1{publicstaticvoidmain(Stringargs[]){if(args.length!=1){System.err.println("
missingfilename");System.exit(1);}try{FileInputStreamfis=newFileInputStream(args[0]);intcnt=0;intb;while((b=fis.read())!=-1){if(b=='\n')cnt++;}fis.close();System.out.println(cnt);}catch(IOExceptione){System.err.println(e);}}}
然而这个方法触发了大量的底层运行时系统调用--FileInputStream.read--返回文件的下一个字节的本机方法。
方法2:使用大缓冲区
第二种方法使用大缓冲区避免了上面的问题:
importjava.io.*;publicclassintro2{publicstaticvoidmain(Stringargs[]){if(args.length!=1){System.err.println("missingfilename");System.exit(1);}try{FileInputStreamfis=newFileInputStream(args[0]);BufferedInputStreambis=newBufferedInputStream(fis);intcnt=0;intb;while((b=bis.read())!=-1){if(b=='\n')cnt++;}bis.close();System.out.println(cnt);}catch(IOExceptione){System.err.println(e);}}}
BufferedInputStream.read从输入缓冲区获取下一个字节,仅仅只访问了一次底层系统。