通过扩展RandomAccessFile类使之具备Buffer改善I/O性能

主体:

目前最流行的J2SDK版本是1.3系列。使用该版本的开发人员需文件随机存取 ,就得使用RandomAccessFile类。其I/O性能较之其它常用开发语言的同类性能 差距甚远,严重影响程序的运行效率。

开发人员迫切需要提高效率,下面分析RandomAccessFile等文件类的源代码 ,找出其中的症结所在,并加以改进优化,创建一个"性/价比"俱佳 的随机文件访问类BufferedRandomAccessFile。

在改进之前先做一个基本测试:逐字节COPY一个12兆的文件(这里牵涉到读 和写)。

耗用时间(秒)
RandomAccessFile RandomAccessFile 95.848
BufferedInputStream + DataInputStream BufferedOutputStream + DataOutputStream 2.935

我们可以看到两者差距约32倍,RandomAccessFile也太慢了。先看看两者关 键部分的源代码,对比分析,找出原因。

1.1.[RandomAccessFile]

public class RandomAccessFile implements DataOutput, DataInput {
  public final byte readByte() throws IOException {
    int ch = this.read();
    if (ch < 0)
      throw new EOFException();
    return (byte)(ch);
  }
  public native int read() throws IOException;
  public final void writeByte(int v) throws IOException {
    write(v);
  }
  public native void write(int b) throws IOException;
}

可见,RandomAccessFile每读/写一个字节就需对磁盘进行一次I/O操作。

1.2.[BufferedInputStream]

public class BufferedInputStream extends FilterInputStream {
  private static int defaultBufferSize = 2048;
  protected byte buf[]; // 建立读缓存区
  public BufferedInputStream(InputStream in, int size) {
    super(in);    
    if (size <= 0) {
      throw new IllegalArgumentException("Buffer size <= 0");
    }
    buf = new byte[size];
  }
  public synchronized int read() throws IOException {
    ensureOpen();
    if (pos >= count) {
      fill();
      if (pos >= count)
        return -1;
    }
    return buf[pos++] & 0xff; // 直接从BUF[]中读取
  }
  private void fill() throws IOException {
  if (markpos < 0)
    pos = 0;    /* no mark: throw away the buffer */
  else if (pos >= buf.length)  /* no room left in buffer */
    if (markpos > 0) {  /* can throw away early part of the buffer */
    int sz = pos - markpos;
    System.arraycopy(buf, markpos, buf, 0, sz);
    pos = sz;
    markpos = 0;
    } else if (buf.length >= marklimit) {
    markpos = -1;  /* buffer got too big, invalidate mark */
    pos = 0;  /* drop buffer contents */
    } else {    /* grow buffer */
    int nsz = pos * 2;
    if (nsz > marklimit)
      nsz = marklimit;
    byte nbuf[] = new byte[nsz];
    System.arraycopy(buf, 0, nbuf, 0, pos);
    buf = nbuf;
    }
  count = pos;
  int n = in.read(buf, pos, buf.length - pos);
  if (n > 0)
    count = n + pos;
  }
}

时间: 2024-09-19 07:21:37

通过扩展RandomAccessFile类使之具备Buffer改善I/O性能的相关文章

深入分析:用1K内存实现高效I/O的RandomAccessFile类的详解_java

主体:目前最流行的J2SDK版本是1.3系列.使用该版本的开发人员需文件随机存取,就得使用RandomAccessFile类.其I/O性能较之其它常用开发语言的同类性能差距甚远,严重影响程序的运行效率.开发人员迫切需要提高效率,下面分析RandomAccessFile等文件类的源代码,找出其中的症结所在,并加以改进优化,创建一个"性/价比"俱佳的随机文件访问类BufferedRandomAccessFile.在改进之前先做一个基本测试:逐字节COPY一个12兆的文件(这里牵涉到读和写)

Silverlight实例教程 - 自定义扩展Validation类,验证框架的总结和建议

Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation 数据验证开篇 Silverlight实例教程 - Validation数据验证基础属性和事件 Silverlight实例教程 - Validation数据验证DataAnnotation机制和调试技巧 Silverlight实例教程 - Validation客户端同步数据验证 Silverlight实例教程 - Validation 服务器端异步数据验证 Silverlight

PHP扩展导出类

php扩展导出类方式比较简单,可以在已经开发好的php扩展上直接应用,不会影响到原先的应用.只需要更改一下xxx.c(xxx为php扩展的C文件名) 第一步,编写如下代码 static zend_function_entry php_my_class_functions[] = { PHP_FALIAS(connect, my_connect, NULL) PHP_FALIAS(close, my_close, NULL) PHP_FALIAS(delete, my_delete, NULL)

java-Java Scanner类使用时产生的一个错误,求解

问题描述 Java Scanner类使用时产生的一个错误,求解 package upper_test; import java.util.*; public class Scanner_00 { int a; long b; float c; String d; Double e; public Scanner_00(String x){ Scanner s=new Scanner(x); a=s.nextInt(); b=s.nextLong(); c=s.nextFloat(); d=s.n

c#-C# 请教这个设置多显示器复制扩展的类怎么调用?麻烦各位了!

问题描述 C# 请教这个设置多显示器复制扩展的类怎么调用?麻烦各位了! #region Copyright (C) 2005-2011 Team MediaPortal// Copyright (C) 2005-2011 Team MediaPortal// http://www.team-mediaportal.com// // MediaPortal is free software: you can redistribute it and/or modify// it under the

RandomAccessFile类实现随机读写文件

 java.io.RandomAccessFile类能够实现对文件内的随机位置进行读写操作.通过下面的一个实例来进行了解. 实例: public class RandomAccessFileDemo03 { public static void main(String[] args) throws IOException{ File f1=new File("e:"+File.separator+"ioString.dat"); RandomAccessFile r

设计-java 字段扩展机制 类扩展机制

问题描述 java 字段扩展机制 类扩展机制 当要求数据库中的一个表里需要进行字段扩展时,如何能让po层中的各个实体也能一起达到扩展的效果呢,数据库里面的表又该如何设计 解决方案 本文转载自:http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/ 简介:? 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟推演了动态代理类的可能实现,向读者阐述了一个完整的 Java 动态代理运作过程,希望能帮助读者加深对 Java

java-Java 中一个类定义的一个静态变量 被另一个类使用时 这个静态变量必须有值吗?

问题描述 Java 中一个类定义的一个静态变量 被另一个类使用时 这个静态变量必须有值吗? Java 中一个类定义的一个静态变量 被另一个类使用时 这个静态变量必须有值吗? 解决方案 可以没有值,但建议赋初始值.静态变量在类加载的时候会执行初始化操作,如果没有显式赋值,则会初始化为默认值,比如int型的就是0,bool类型的就是false,如果是对象的话,就是null,其它类调用时如果没有显式赋初始值,有可能导致逻辑问题,比如空指针异常等等. 解决方案二: Can be no value, bu

CodeIgniter扩展核心类实例详解_php实例

本文实例讲述了CodeIgniter扩展核心类的方法.分享给大家供大家参考,具体如下: CI中对核心类.辅助类和函数的扩展是相当方便的,配置文件中指定了subclass_prefix扩展前缀,默认为MY_,扩展时需要以该配置为前缀,下面整理下扩展方式. 1.扩展核心类 核心类位于system/core下,其中大部分类会在初始化的时候自动加载.扩展核心类的方式有两种:替换核心类和继承核心类. 替换核心类 当application/core目录下存在与system/core同名的文件时会自动替换掉核