一、使用直接缓冲区完成文件的复制 ( 内存映射文件 )



JDK 1.7 后 提供

image.png

image.png

image.png

image.png
上面的 create 的话就是:
不存在就创建
存在的话就覆盖..




  
  /**  
   *  2. 使用 直接缓冲区 完成文件的复制 (内存映射文件) 
   *   直接缓冲区 -->  只有 byte 支持 
   */
@Test  
public void test2(){  
  
    FileChannel inChannel = null;  
  FileChannel outChannle = null;  
  
 try {  
        inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);  
  
  outChannle = FileChannel.open(Paths.get("3.jpg"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE\_NEW);  
  
  // 这个就是 内存映射文件  
  MappedByteBuffer inMappedBuf = inChannel.map(FileChannel.MapMode.READ\_ONLY, 0 , inChannel.size());  
  MappedByteBuffer outMappedBuf = outChannle.map(FileChannel.MapMode.READ\_WRITE, 0, inChannel.size());  
  // 上面的两个内存映射文件都在 物理内存中....  
  
  
 // 现在的优点, 只需要从缓冲区中读写操作..  
 byte[] dst = new byte[inMappedBuf.limit()];  
  
  inMappedBuf.get(dst);  
  outMappedBuf.put(dst);  
  
  } catch (IOException e) {  
        e.printStackTrace();  
  } finally {  
        if(inChannel != null){  
            try {  
                inChannel.close();  
  } catch (IOException e) {  
                e.printStackTrace();  
  }  
        }  
  
        if(outChannle != null){  
            try {  
                outChannle.close();  
  } catch (IOException e) {  
                e.printStackTrace();  
  }  
        }  
  
    }  
  
}



二、 利用通道完成文件的复制 (非直接缓冲区的)




  
/\*\*  
 \*    1. 利用通道完成文件的复制  (非直接缓冲区的) \*/@Test  
public void test1(){  
  
    FileInputStream fis = null;  
  FileOutputStream fos = null;  
  FileChannel inChannel = null;  
  FileChannel outChannel = null;  
  
 try {  
        fis = new FileInputStream("1.jpg");  
  fos = new FileOutputStream("2.jpg");  
  
  // 1. 获取通道  
  inChannel = fis.getChannel();  
  outChannel = fos.getChannel();  
  
  // 2. 分配指定大小的缓冲区.  
  ByteBuffer buf = ByteBuffer.allocate(1024);  
  
  
  // 3. 读取数据  
 // 将 通道中的数据存入缓冲区中  while(inChannel.read(buf) != -1){  
            // 切换成读取数据模式  
  buf.flip();  
  
  // 4. 写入数据  
 // 将缓存区的数据写入到 通道中  outChannel.write(buf);  
  
  // 清空缓冲区  
  buf.clear();  
  }  
  
  
    } catch (IOException e) {  
        e.printStackTrace();  
  } finally {  
        if(outChannel != null){  
            try {  
                outChannel.close();  
  } catch (IOException e) {  
                e.printStackTrace();  
  }  
        }  
  
        if(inChannel != null){  
            try {  
                inChannel.close();  
  } catch (IOException e) {  
                e.printStackTrace();  
  }  
        }  
  
        if(fos != null){  
            try {  
                fos.close();  
  } catch (IOException e) {  
                e.printStackTrace();  
  }  
        }  
  
        if(fis != null){  
            try {  
                fis.close();  
  } catch (IOException e) {  
                e.printStackTrace();  
  }  
        }  
  
    }  
  
}



三、通道之间的数据传输



/\*\*  
 \*  通道之间的数据传输 \*/@Test  
public void test3(){  
    FileChannel inChannel = null;  
  FileChannel outChannle = null;  
  
 try {  
        inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);  
  
  outChannle = FileChannel.open(Paths.get("4.jpg"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE\_NEW);  
  
  inChannel.transferTo(0, inChannel.size(), outChannle);  
  
  // 这个 outChannel 也行...  
 //   outChannle.transferFrom(inChannel, 0, inChannel.size());  
  }catch (IOException e){  
        e.printStackTrace();  
  } finally {  
        if(inChannel != null){  
            try {  
                inChannel.close();  
  } catch (IOException e) {  
                e.printStackTrace();  
  }  
        }  
  
        if(outChannle != null){  
            try {  
                outChannle.close();  
  } catch (IOException e) {  
                e.printStackTrace();  
  }  
        }  
    }  
  
}


lankeren
44 声望6 粉丝

有效果,达到目标的努力是真努力,其余不能称之为努力。