Java 用 ByteBuffer和RandomAccessFile 写大文件

本文通过两个不同的方法,对比了使用 Java NIO 和传统 RandomAccessFile 进行文件写入操作的性能差异。测试表明,在不同文件大小下,利用 ByteBuffer 的方式能够显著提高文件写入效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
  
public class Test1 {
     public static void main(String[] args) throws Exception {
         test1( "D:/test1.tmp" , 1000000 );
         test2( "D:/test2.tmp" , 1000000 , 1024 );
         test2( "D:/test3.tmp" , 1000000 , 1024 * 1024 );
     }
  
     public static void test2(String file, int loop, int mapsize) throws Exception {
         //先将上次文件删除
         new File(file).delete();
         RandomAccessFile raf1 = new RandomAccessFile(file, "rw" );
  
         FileChannel fc = raf1.getChannel();
         ByteBuffer raf = ByteBuffer.allocate(mapsize);
         System.out.println(file+ " order " +raf.order());
         raf.clear();
         //在windows7 32bit 下, allocateDirect反而比allocate慢
         //ByteBuffer raf = ByteBuffer.allocateDirect(mapsize);
          
         byte [] b1 = new byte []{ 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' };
         byte [] utfstr = "this is a test" .getBytes( "UTF-8" );
         long s = System.nanoTime();
         for ( int i= 0 ;i<loop;i++){
             raf.put(b1);
             raf.putInt(i);
             raf.putInt(i+ 1 );
              
             raf.put(utfstr);
             raf.put(( byte ) '/n' );
              
             if (raf.remaining()< 30 ){
                 raf.flip(); //因为下行的fc.write将会读取raf的内容, 所以先flip一下
                 fc.write(raf);
                 //raf.clear();
                 raf.compact(); //因为fc.write(x)可能没有完全将raf的内容写入, 所以调用compact比clear安全,经过测试compact不比clear慢
             }
         }
         raf.flip();
         fc.write(raf);
         long d = System.nanoTime() - s;
         fc.close();
         raf1.close();
         System.out.println(file+ " spent time=" +(d/ 1000000 ));
     }
      
     /**
      * @param args
      */
     public static void test1(String file, int loop) throws Exception {
         new File(file).delete();
         RandomAccessFile raf = new RandomAccessFile(file, "rw" );
          
          
         byte [] b1 = new byte []{ 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' };
         byte [] utfstr = "this is a test" .getBytes( "UTF-8" );
         long s = System.nanoTime();
         //for(int i=0;i<1000000;i++){
         for ( int i= 0 ;i<loop;i++){
             raf.write(b1);
             raf.writeInt(i);
             raf.writeInt(i+ 1 );
             raf.write(utfstr);
             raf.write( '/n' );
         }
         long d = System.nanoTime() - s;
         raf.close();
         System.out.println(file+ " spent time=" +(d/ 1000000 ));
     }
  
}

在我机器上的3次运行结果:

第一次:

D:/test1.tmp spent time=95519

D:/test2.tmp spent time=936

D:/test3.tmp spent time=420

第二次:
D:/test1.tmp spent time=96731

D:/test2.tmp spent time=831

D:/test3.tmp spent time=402

第三次:
D:/test1.tmp spent time=97534

D:/test2.tmp spent time=870

D:/test3.tmp spent time=425

 

 

http://www.smithfox.com/?e=148

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帆软爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值