package com.nio.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import org.junit.Test; /**
*
* @author fliay
*
* 一、通道(channel): 用于源节点与目标节点的连接。在JavaNIO中负责缓冲区中数据的传输。
* Channel本身不存在存数据,因此需要配合缓冲区进行传输。
*
* 二、通道的主要实体类
* |--FileChannel
* |--SocketChannel
* |--ServerSocketChannel
* |--DatagramChannel
*
* 三、获取通道 1.Java针对支持通道的类提供了getChannel()方法 本地IO:
* FileInputStream/FileOutputStream RandomAccessFile
*
* 网络IO
* |--Socket
* |--ServerSocket
* |--DatagramSocket
*
* 2.在JDK1.7中的NIO.2针对各个通道提供了静态方法open()
* 3.在JDK1.7中的NIO.2的file工具类的newByteChannel()
*
* 四、通道之间的数据传输
* transferFrom()
* transferTo()
*
* 五、分散(Scatter)与聚集()
*
*/
public class TestChannel { // 利用通道完成文件的复制
@Test
public void test1() {
long start = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
// cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408 大小为3.42G
fis = new FileInputStream("/虚拟机/cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso");
fos = new FileOutputStream("/开发/cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso");
// 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 (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
outChannel.close();
inChannel.close();
fos.close();
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
long end = System.currentTimeMillis(); System.out.println("消耗时间为:" + (end - start));
}
// 消耗时间为:12651 // 使用直接缓冲区完成文件的复制(内存映射文件)
@Test
public void Test2() throws IOException {
long start = System.currentTimeMillis();
FileChannel inChannel = FileChannel.open(Paths.get("/虚拟机/cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso"),
StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("/开发/cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso"),
StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
// long[] sizes = new long[3];
// 如果文件过长的话会报错 Size exceeds Integer.MAX_VALUE 可以通过对文件进行分批存
// sizes[0]=0;
// sizes[1]=inChannel.size()/2;
// sizes[2]=inChannel.size()-inChannel.size()/2;
// for(int i=0;i<sizes.length-1;i++){
// //内存映射文件
// MappedByteBuffer inMappedBuf = inChannel.map(MapMode.READ_ONLY,
// sizes[i],sizes[i+1]);
// MappedByteBuffer outMappedBuf = outChannel.map(MapMode.READ_WRITE,
// sizes[i],sizes[i+1]);
// //直接对缓冲区进行数据的读写操作
// byte[] dst = new byte[inMappedBuf.limit()];
// inMappedBuf.get(dst);
// outMappedBuf.put(dst);
// }
// 内存映射文件
MappedByteBuffer inMappedBuf = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
MappedByteBuffer outMappedBuf = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
// 直接对缓冲区进行数据的读写操作
byte[] dst = new byte[inMappedBuf.limit()];
inMappedBuf.get(dst);
outMappedBuf.put(dst);
inChannel.close();
outChannel.close();
long end = System.currentTimeMillis();
System.out.println("消耗时间为:" + (end - start)); }// 执行时间6161 // 通道之间的数据传输
@Test
public void Test3() throws IOException {
long start = System.currentTimeMillis();
FileChannel inChannel = FileChannel.open(Paths.get("/虚拟机/cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso"),
StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("/开发/cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso"),
StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
// inChannel.transferTo(0, inChannel.size(), outChannel);//执行时间为3957
// 但是文件为拷贝完,只拷贝了2/3
outChannel.transferFrom(inChannel, 0, inChannel.size());// 执行时间8313 成功拷贝
inChannel.close();
outChannel.close();
long end = System.currentTimeMillis();
System.out.println("消耗时间为:" + (end - start));
} //分散和聚集
@Test
public void Test4() throws IOException{
RandomAccessFile ref1 = new RandomAccessFile("/Study/JavaSite/JaveNIO/src/main/java/com/nio/test/TestChannel.java","rw");
//1.获取通道
FileChannel channel1 = ref1.getChannel();
//2.分配指定大小的缓冲区
ByteBuffer buf1 = ByteBuffer.allocate(100);
ByteBuffer buf2 = ByteBuffer.allocate(1024);
//3.分散读取
ByteBuffer[] bufs ={buf1,buf2};
channel1.read(bufs);
for(ByteBuffer byteBuffer:bufs){
byteBuffer.flip();
}
System.out.println(new String(bufs[0].array(),0,bufs[0].limit()));
System.out.println("----------------------------------------");
System.out.println(new String(bufs[1].array(),0,bufs[1].limit()));
//4.聚集写入
RandomAccessFile ref2 = new RandomAccessFile("/Study/JavaSite/JaveNIO/src/main/java/com/nio/test/TestChannel2.java","rw");
FileChannel channel2 = ref2.getChannel();
channel2.write(bufs); } }

  

05-11 12:49