大话NIO---通道

1.简介

通道(Channel):表示IO源与目标打开的连接。Channel不能直接访问数据,需要和Buffer进行交互。

2.通道的主要实现类

java.nio.channels.Channel接口

FileChannel

SocketChannel

ServerSocketChannel

DatagramChannel

3.获取通道

1.java针对支持通道的类提供了getChannel方法

本地IO:

FileInputStream,FileOutputStram

RandomAccessFile

网络IO:

TCP:Socket,ServerSocket

UDP:DataGramSocket

2.提供了静态方法open()

3.Files工具类的newByteChannel()

4.实例

package test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
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.jupiter.api.Test;


public class NIO {
	@Test
	public void test1() throws Exception {
		FileInputStream in = new FileInputStream("panda.jpg");
		FileOutputStream out = new FileOutputStream("copy.jpg");
		
		//获取通道
		FileChannel inchannel = in.getChannel();
		FileChannel outchannel = out.getChannel();
		
		//指定缓冲区大小
		ByteBuffer buf = ByteBuffer.allocate(1024);
		
		//把数据写入缓冲区
		while(inchannel.read(buf)!=-1) {
			buf.flip();//切换成读模式
			//将缓冲区的数据写入通道
			outchannel.write(buf);
			buf.clear();
		}
		outchannel.close();
		inchannel.close();
		out.close();
		in.close();
	}
	//使用直接缓冲区完成文件复制
	@Test
	public void test2() throws IOException {
		FileChannel inChannel = FileChannel.open(Paths.get("panda.jpg"), 
				StandardOpenOption.READ);
		FileChannel outChannel = FileChannel.open(Paths.get("copy2.jpg"), 
				StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE);
		
		//内存映射文件
		MappedByteBuffer inMap = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
		MappedByteBuffer outMap = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
		
		//直接对缓冲区进行数据的读写
		byte [] dest = new byte[inMap.limit()];
		inMap.get(dest);
		outMap.put(dest);
		
		inChannel.close();
		outChannel.close();
	}

}

 

5.分散和聚集

分散:从Channel中读取的数据分散到多个Buffer中(按顺序一次填满每一个缓冲区)

聚集:从对个Buffer中得到数据聚集到Channel(按顺序写入)

package 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.jupiter.api.Test;


public class NIO {
	@Test
	public void test1() throws Exception {
		FileInputStream in = new FileInputStream("panda.jpg");
		FileOutputStream out = new FileOutputStream("copy.jpg");
		
		//获取通道
		FileChannel inchannel = in.getChannel();
		FileChannel outchannel = out.getChannel();
		
		//指定缓冲区大小
		ByteBuffer buf = ByteBuffer.allocate(1024);
		
		//把数据写入缓冲区
		while(inchannel.read(buf)!=-1) {
			buf.flip();//切换成读模式
			//将缓冲区的数据写入通道
			outchannel.write(buf);
			buf.clear();
		}
		outchannel.close();
		inchannel.close();
		out.close();
		in.close();
	}
	//使用直接缓冲区完成文件复制
	@Test
	public void test2() throws IOException {
		FileChannel inChannel = FileChannel.open(Paths.get("panda.jpg"), 
				StandardOpenOption.READ);
		FileChannel outChannel = FileChannel.open(Paths.get("copy2.jpg"), 
				StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE);
		
		//内存映射文件
		MappedByteBuffer inMap = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
		MappedByteBuffer outMap = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
		
		//直接对缓冲区进行数据的读写
		byte [] dest = new byte[inMap.limit()];
		inMap.get(dest);
		outMap.put(dest);
		
		inChannel.close();
		outChannel.close();
	}
	
	@Test
	public void test3() throws Exception {
		RandomAccessFile ranf1 = new RandomAccessFile("A0A0A0MRZ8.txt", "rw");
		
		FileChannel fc1 = ranf1.getChannel();
		
		ByteBuffer buf1 = ByteBuffer.allocate(100);
		ByteBuffer buf2 = ByteBuffer.allocate(1024);
		
		//分散读取
		ByteBuffer [] bufs = {buf1,buf2};
		fc1.read(bufs);
		for (ByteBuffer byteBuffer : bufs) {
			byteBuffer.flip();
		}
		System.out.println(new String (bufs[0].array(),0,bufs[0].limit()));
		System.out.println(new String (bufs[1].array(),0,bufs[1].limit()));
		
		//聚集写入
		RandomAccessFile ranf2 = new RandomAccessFile("COPY.txt", "rw");
		FileChannel fc2 = ranf2.getChannel();
		fc2.write(bufs);
	}

}

 

转载于:https://my.oschina.net/u/4094176/blog/3026449

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值