有以下这样的一个类public class TestData {    private boolean transactionFlag;
    private boolean success;
    private long timpStamp;
    private long bytes;
    private int elapsed;
    private String responseCode;
    private String label;
    private String threadName;
}想把这个类的内容输出到binary文件, 大致一共有500万个对象。我测试了下,10万个的读,就用了6秒。 有点慢了。 我想知道怎么读写binary文件更快呢?
貌似C的函数很快的。
Date d = new Date();
String inputputFileName = "c:\\testb";
SampleData sampleData = null; RandomAccessFile ra = null;
try {
ra = new RandomAccessFile(inputputFileName,"r"); sampleData = new SampleData();
for (int i = 0; i < size; i++) {
sampleData.readFromBinary(ra);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException ie) {
ie.printStackTrace();
} try {
if (ra != null) {
ra.close();
}
} catch (IOException e) {
e.printStackTrace();
}
Date l = new Date();
System.out.println("End! " + (l.getTime() - d.getTime()));    public void readFromBinary(RandomAccessFile file) throws IOException {
     transactionFlag = file.readBoolean();
     success = file.readBoolean();
     timpStamp = file.readLong();
     bytes = file.readLong();
     elapsed = file.readInt();     responseCode = file.readUTF();
     label = file.readUTF();
     threadName = file.readUTF();
    }

解决方案 »

  1.   

    也差不多就是这个性能了
    java本来就没有c的速度快
    更别说处理io了
    还500万个对象,呵呵
      

  2.   


    我看RandomAccessFile的javadoc里有 FileChannel
    MappedByteBuffer map(FileChannel.MapMode mode, long position, long size) 
    什么的。是不是用了这个会快呢?MappedByteBuffer里没有getBoolean 和putBoolean函数。 很奇怪啊。
      

  3.   

    把try,catch去掉,在方法声明throws如何呢?
      

  4.   

    这个有异常会处理 基本不会出异常的 所以不会走这个path的 也不会额外消耗时间的
      

  5.   


    能说具体点吗?
    听说1.4以后RandomAccessFile被重构了,已经使用了nio包的内容了。
      

  6.   

    用Java New I/O吧,试试内存映射文件或者缓冲区数据结构。
      

  7.   

    还有一个方法
    如果你的硬件状况不错的话
    可以考虑提高jvm虚拟内存,扩到1024m,或者更大
      

  8.   

    NIO的用法挺麻烦的,我看thinking in java里说,RandomAccessFile类的低层用NIO的原理重写过了,也就是说用RandomAccessFile等文件读写的类已经使用了NIO的技术了。
      

  9.   


       int bufSize = 1024;
        byte[] bs = new byte[bufSize];
        ByteBuffer byteBuf = ByteBuffer.allocate(bufSize);
        try {
        FileChannel channel = new RandomAccessFile("c:\\testb","r").getChannel();
        int n;
        while(channel.read(byteBuf) != -1) {
          n = byteBuf.position();
          byteBuf.rewind();
          byteBuf.get(bs);       //System.out.print(new String(bs, 0, n));
          byteBuf.clear();
        }
        } catch (FileNotFoundException e) {
    e.printStackTrace();
    } catch (IOException ie) {
    ie.printStackTrace();
    }这样来读可以快很多。 基本10万个,0.1秒就好了。 但是我怎么把byteBuf正确的转成类的对象呢?
      

  10.   

    NEW IO 内存映射应该可以更快一点
      

  11.   

    我觉得在输出输出时提供一个缓冲区可能会提高一些性能,但是和c比还是不行的,毕竟c语言是直接和cpu打交道的吗!
      

  12.   


    要性能,改用c吧!要编码方便取java!鱼和熊掌不能兼得的!
      

  13.   


    buffer,用java.nio.ByteBuffer类,可以用其方法读int,double之类的数据,但没提供读字符串的方法.
      

  14.   

    可以好好研究一下二进制文件的结构,你用RandomAccessFile怎么能读到字符串呢?是不是字符串之前有两个字节是放字符串的长度的?如果是那就好办了,可以根据这个整数把后面的字符串读出来。如果不是你在写数据据时,可以人为的加上。
      

  15.   

    二进制的话就用 BufferedOutputStream 吧
      

  16.   

    我用ObjectOutputStream
    10w个3.8秒
    但是500w个 OutOfMemoryError: Java heap space
      

  17.   

    用 nio 不见得比一般的 io 快,我以前做过相关的测试,也阅读过 nio 的某些实现源代码,就我的感觉 nio 的机制在对IO速度提升上起不到什么帮助nio 的提出好象并不是为了解决IO的速度问题,它主要是用来简化多线程情况下读和写的协调问题
      

  18.   

    为了提高性能,io包里面的大部分流都经过new io改造过
      

  19.   

    我是楼主。 在别的网站找到结果了。  File file = new File("product.dat");   
      DataInputStream  in = new DataInputStream(new BufferedInputStream(new FileInputStream(file))); 这样做读取500万个对象只要6秒左右。http://ajava.org/code/io/360.html
      

  20.   

    据说引入java.nio包,RandomAccessFile被重构了,性能有了非常大的提升
      

  21.   

    import java.io.BufferedOutputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;public class TestWrite { public static void main(String[] args)throws Exception {
    long sTime = System.currentTimeMillis();

    ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("d:\\zip\\bigData.txt")));
    TestData td = new TestData();
    long count = 500 * 10000 ;
    for( ; count > 0; count--) {
    oos.writeObject(td);
    } oos.close();
    System.out.print(System.currentTimeMillis() - sTime);
    }}class TestData implements Serializable {    private boolean transactionFlag;
        private boolean success;
        private long timpStamp;
        private long bytes;
        private int elapsed;
        private String responseCode;
        private String label;
        private String threadName;
    }控制台输出: 1622注:
    1. 这里都是写入同一个对象,而不是new了500W个对象来写入.
    2. 生成的文件大小为23.8 MB