调整javatm 的i/o性能
这篇文章讨论并举例阐述了提高javatm i/o性能的多种技术。绝大多数技术是围绕着磁盘文件i/o的调整来谈 的,但是,有些技术对网络i/o和视窗输出也同样适用。首先介绍的技术包含底层i/o问题,然后对诸如压 缩、格式化和序列化这样的高层i/o进行讨论。但是,请注意,本讨论不涉及应用设计问题, 搜索算法和数 据结构的选择,也不讨论类似文件高速缓存(file caching)这样的系统级问题。
当讨论java i/o时,java编程语言所假定的两种不同的磁盘文件组织是没有任何意义的。这两种磁盘文件组 织,一种基于字节流,另一种基于字符序列。在 java语言中,一个字符使用两个字节表示,而不是象c语言 那样使用一个字节表示一个字符。正因为如此,从文件中读取字符时需要一些转换。在某些情况下,这样的 区别非常重要,我们将用几个例子对此进行说明。
底层i/o问题
简介
加速i/o的基本规则
缓冲
读/写文本文件
格式化的开销
随机存储
高层i/o问题
压缩
高速缓存
标志化(tokenization)
序列化(serialization)
获取文件信息
更多的信息
加速i/o的基本规则
作为开始讨论的一种方法,下面列出了加速i/o的一些基本规则:
1.避免访问磁盘
2.避免访问下面的操作系统
3.避免方法调用
4.避免对字节和字符的单独处理
显然,这些规则不能被全面而严格地应用,因为如果那样的话,i/o就不可能工作了。但是,为了查看规则是 如何被应用的,就考虑下面的三个例子,这些例子计算一个文件中换行符('/n')的数目。
方法一:读取的方法
第一个方法简单地利用一个文件输入流(fileinputstream)上的读方法:
import java.io.*;
public class intro1 {
public static void main(string args[]) {
if (args.length != 1) {
system.err.println("missing filename");
system.exit(1);
}
try {
fileinputstream fis =
new fileinputstream(args[0]);
int cnt = 0;
int b;
while ((b = fis.read()) != -1) {
if (b == '/n')
cnt++;
}
fis.close();
system.out.println(cnt);
}
catch (ioexception e) {
system.err.println(e);
}
}
}
然而,这个方法触发了大量对底层运行系统的调用,这就是fileinputstream.read, 返回文件下一个字节的本 机方法。
方法二:采用一个大缓冲区
第二种方法通过采用一个大缓冲区,避免了上述问题:
import java.io.*;
public class intro2 {
public static void main(string args[]) {
if (args.length != 1) {
system.err.println("missing filename");
system.exit(1);
}
try {
fileinputstream fis =
new fileinputstream(args[0]);
bufferedinputstream bis =
new bufferedinputstream(fis);
int cnt = 0;
int b;
while ((b = bis.read()) != -1) {
if (b == '/n')
cnt++;
}
bis.close();
system.out.println(cnt);
}
catch (ioexception e) {
system.err.println(e);
}
&
闽公网安备 35060202000074号