JAVANIO通道

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);
		
		
	}
	
}

  

原文地址:https://www.cnblogs.com/fliay/p/7277237.html