欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

通过nio的Channel-Buffer来读写文件

程序员文章站 2022-05-30 21:53:06
...

 

// 通过nio的Channel来读写文件
public class NioFileReadWrite {

 public static void main(String[] args) {
  String file = "d:\\n4.txt";
  String file2 = "d:\\ncc.txt";
  
  // 1.通过Channel-Buffer进行文件读写
//  new Thread(new ReadFileThread(file, file2)).start();
  
  // 2.内存映射文件读取: 速度快                   MappedByteBuffer
  new Thread(new MapFileReadThread(file)).start();
 }

 static class ReadFileThread implements Runnable{
  private String file;
  private String file2;
  
  public ReadFileThread(String file, String file2){
   this.file = file;
   this.file2 = file2;
  }
  
  public void run(){
   try{
    int num = 1024;
    int k =0;
    FileInputStream fis = new FileInputStream(file); 
    FileOutputStream fos = new FileOutputStream(file2);
     
          // 1.从FileInputStream对象获取文件通道FileChannel 
          FileChannel channel = fis.getChannel(); 
          FileChannel channel2 = fos.getChannel();
         
          long size = channel.size(); 
   
          // 2.从通道读取文件内容 
          byte[] bytes = new byte[num]; 
          ByteBuffer byteBuffer = ByteBuffer.allocate(num); 
   
          // 每次read都将读取 allocate 个字节到ByteBuffer 
          int len = -1; 
          while ((len = channel.read(byteBuffer)) != -1) { 
              // 注意先调用flip方法反转Buffer,再从Buffer读取数据 
              byteBuffer.flip(); 
               
              // 有几种方式可以操作ByteBuffer 
              // 1.可以将当前Buffer包含的字节数组全部读取出来 
              //bytes = byteBuffer.array(); 
              // System.out.print(new String(bytes)); 
               
              // 2.类似与InputStrean的read(byte[],offset,len)方法读取  
//              byteBuffer.get(bytes, 0, len); 
//              System.out.print(new String(bytes, 0 ,len)); 

              channel2.write(byteBuffer);
              // 最后注意调用clear方法,将Buffer的位置回归到0 
              byteBuffer.clear(); 
              k++;
          } 
         
          System.out.println("k="+k);
          // 关闭通道和文件流 
          channel.close(); 
          fis.close(); 
          channel2.close();
          fos.close();
   }catch(Exception e){
    e.printStackTrace();
   }
  }
 }
 
 static class MapFileReadThread implements Runnable{
  private String file;
  public MapFileReadThread(String file){
   this.file = file;
  }

  public void run() {
   try{
    int num = 1024;
    RandomAccessFile fis = new RandomAccessFile(new File(file), "rw"); 
          FileChannel channel = fis.getChannel(); 
          long size = channel.size(); 
           
          // 构建一个只读的MappedByteBuffer 
          MappedByteBuffer mappedByteBuffer = channel.map(MapMode.READ_ONLY, 0, size); 
           
          // 如果文件不大,可以选择一次性读取到数组 
          // byte[] all = new byte[(int)size]; 
          // mappedByteBuffer.get(all, 0, (int)size); 
           
          // 如果文件内容很大,可以循环读取,计算应该读取多少次 
          byte[] bytes = new byte[num]; 
          long cycle = size / num; 
          int mode = (int)(size % num); 
          for (int i = 0; i < cycle; i++) { 
              // 每次读取allocate个字节 
              mappedByteBuffer.get(bytes); 
               
              // 打印文件内容,关闭打印速度会很快 
               System.out.print(new String(bytes)); 
          } 
          if(mode > 0) { 
              bytes = new byte[mode]; 
              mappedByteBuffer.get(bytes); 
              System.out.print(new String(bytes));
          } 
   
          // 关闭通道和文件流 
          channel.close(); 
          fis.close();
   }catch(Exception e){
    e.printStackTrace();
   }
  }
  
 }
}

相关标签: nio