天天看點

NIO - MappedByteBuffer

  *MappedByteBuffer的建立

  在FileChannel上調用map方法 傳回一個MappedByteBuffer對象  

public MappedByteBuffer map(MapMode mode, long position, long size)      

  MapMode  映射模式(MapMode 是FileChannel中的一個内部類) 有三個可選值

   1.READ_ONLY    隻讀映射模式

   2.READ_WRITE  讀/寫映射模式

   3.PRIVATE           通過put方法對MappedByteBuffer的修改   不會修改到磁盤檔案  隻是虛拟記憶體的修改

*MappedByteBuffer在父類ByteBuffer的基礎上 新增的幾個方法

   1.fore緩沖區在READ_WRITE模式下,此方法對緩沖區所做的内容更改強制寫入檔案

   2.load:将緩沖區的内容載入實體記憶體,并傳回該緩沖區的引用

private final static Charset charset = Charset.forName("GBK");  

  /**
   * 讀檔案
   * <br>------------------------------<br>
   * @param path
   * @return
   * @throws IOException
   */
  private static String read(String path) throws IOException {
    if (path == null || path.length() == 0) return null;
    FileInputStream fileInputStream =  new FileInputStream(path);
    FileChannel fileChannel =  fileInputStream.getChannel();
    MappedByteBuffer mappedByteBuffer = fileChannel.map(MapMode.READ_ONLY, 0, fileChannel.size());
    fileInputStream.close();
    fileChannel.close();
    String str = charset.decode(mappedByteBuffer).toString();
    mappedByteBuffer = null;
    return str;
  }

  /**
   * 追加内容
   * <br>------------------------------<br>
   * @param path
   * @param str
   * @return
   * @throws IOException
   */
  private static MappedByteBuffer append(String path, String str) throws IOException {
    if (str == null || str.length() == 0) return null;
    RandomAccessFile randomAccessFile = new RandomAccessFile(path, "rw");
    FileChannel fileChannel = randomAccessFile.getChannel();
    byte[] bytes = str.getBytes();
    long size = fileChannel.size() + bytes.length;
    MappedByteBuffer mappedByteBuffer = fileChannel.map(MapMode.READ_WRITE, 0, size);
    fileChannel.close();
    randomAccessFile.close();

    int position = mappedByteBuffer.limit() - bytes.length;
    mappedByteBuffer.position(position);
    mappedByteBuffer.put(bytes);
    mappedByteBuffer.force();
    mappedByteBuffer.flip();
    return mappedByteBuffer;
  }

  /**
   * 檔案複制
   * <br>------------------------------<br>
   * @param srcfilePath
   * @param targetPath
   * @throws IOException 
   */
  private static void copy(String srcfilePath, String targetPath) throws IOException { 
    File file = new File(targetPath);  
    if (!file.getParentFile().exists()) {  
      file.mkdirs();  
    }  
    RandomAccessFile inRandomAccessFile = new RandomAccessFile(srcfilePath, "r");
    FileChannel inFileChannel = inRandomAccessFile.getChannel();
    MappedByteBuffer inMappedByteBuffer = inFileChannel.map(MapMode.READ_ONLY, 0, inFileChannel.size());
    inRandomAccessFile.close();
    inFileChannel.close();

    RandomAccessFile outRandomAccessFile = new RandomAccessFile(targetPath, "rw");
    FileChannel outFileChannel = outRandomAccessFile.getChannel();
    MappedByteBuffer outMappedByteBuffer = outFileChannel.map(MapMode.READ_WRITE, 0, inMappedByteBuffer.capacity());
    outMappedByteBuffer.put(inMappedByteBuffer);
    outMappedByteBuffer.force();
    outRandomAccessFile.close();
    outFileChannel.close();
    outMappedByteBuffer.flip();
  }

  /**
   * 不會更新到檔案 隻會更新虛拟記憶體 
   * <br>------------------------------<br>
   * @param path
   * @param str
   * @return
   * @throws IOException
   */
  private static MappedByteBuffer doTestPrivateMode(String path, String str) throws IOException {
    if (str == null || str.length() == 0) return null;
    RandomAccessFile randomAccessFile = new RandomAccessFile(path, "rw");
    FileChannel fileChannel = randomAccessFile.getChannel();
    byte[] bytes = str.getBytes();
    long size = fileChannel.size() + bytes.length;
    MappedByteBuffer mappedByteBuffer = fileChannel.map(MapMode.PRIVATE, 0, size);
    mappedByteBuffer.put(bytes);
    fileChannel.close();
    randomAccessFile.close();

    mappedByteBuffer.flip();
    System.out.println(charset.decode(mappedByteBuffer));
    return mappedByteBuffer;
  }      

繼續閱讀