java中关于I/O的效率问题

来源:互联网 发布:金山毒霸软件下载 编辑:程序博客网 时间:2024/05/16 15:36
下面是针对不同类型大小的文件的具体操作,以我的测试例子说明:对于4M以上的使用FileChannnel的transferTo或者transferFrom的效率将是Inputstream或者OutputStream的两倍以上。实验结果证实:stream流适合小型文件的操作FileChannnel适合较大文件的操作,还有对于几十M或者几个G的文件操作应该使用FileChannel的map()方法(内存文件映射机制),FileChannel的内存文件映射是直接调用操作系统的内存文件映射机制,效率上和c++接近。使用内存文件映射必须使用RandomAccessFile(随机访问文件的读写操作),RandomAccessFile不同于Stream,他是独立的可以进行随机读写操作,可以一次读入一个字节数组或者写入一个字节数组。
package com.test.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
/**
* 大文件操作以及文件的复制
* @author 陈双
*
*/
public class Test {
   public static void main(String[] args)
   {
    try {
     long start=System.currentTimeMillis();
      //copyWithStream(new File("d:\\student.txt"), new File("d:\\stu.txt"));
     copyWithChannel(new File("d:\\student.txt"), new File("d:\\stu.txt"));
     long end=System.currentTimeMillis();
     System.out.println("cost "+(end-start)+"ms");
} catch (Exception e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}
   }
   /**
    * 当读取大文件时需要部分映射,才能完成大文件的读取和修改操作
    * @param file
    * @throws IOException
    */
   public static void mappedMemery(File file) throws IOException
   {
  //以随机读写的方式打开文件
    RandomAccessFile raf=new RandomAccessFile(file,"rw");
    FileChannel channel=raf.getChannel();//获取文件通道
    //内存映射
    MappedByteBuffer mb=channel.map(FileChannel.MapMode.READ_WRITE, 0, channel.size());
    FileLock fl=channel.lock();//文件独占锁,用于写入操作
    mb.put("row".getBytes());//写入操作
    fl.release();//写完之后释放锁
   }
   /**
    * 通过文件通道复制文件,合适较大文件的操作例如对4Mb以上的文件操作就可以看出效率问题
    * @param source
    * @param dest
* @throws IOException
    */
   public static void copyWithChannel(File source,File dest) throws IOException
   {
    FileChannel inChannel;
    FileChannel outChannel;
    FileInputStream in=new FileInputStream(source);
    FileOutputStream out=new FileOutputStream(dest);
    inChannel=in.getChannel();
    outChannel=out.getChannel();
    //将字节从此通道(inChannel)的文件传输到给定的可写入字节通道(outChannel)。
    inChannel.transferTo(0, inChannel.size(), outChannel);
    //将字节从给定的可读取字节通道(inChannel)传输到outChannel通道的文件中。
    //outChannel.transferFrom(inChannel, 0, inChannel.size());
    inChannel.close();
    outChannel.close();
    in.close();
    out.close();
   }
   /**
    * 通过文件流复制文件,适合小文件的操作效率会很高例如4兆一下的文件效果明显
    * @param source
    * @param dest
    * @throws IOException
    */
   public static void copyWithStream(File source,File dest) throws IOException
   {
    BufferedInputStream in=new BufferedInputStream(new FileInputStream(source));
    BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(dest));
    int count=0;
    byte[] buffer=new byte[1024*5];
    while(count!=-1)
    {
     count=in.read(buffer);
     if(count>0)
     {
      out.write(buffer);
     }
    }
    in.close();
    out.close();
   }
}
原创粉丝点击