java nio

io:面向流。阻塞式IO,将他的输入输出看成水流

NIO:面向缓冲区,非阻塞式,将他的通道看成铁路,缓冲区拿数据,底层是数组

package test;

import java.nio.ByteBuffer;

//缓冲区,除了boolean类型都有对象的缓冲区
//如bytebuffer
//通过allocate分配缓冲区的大小
//通过put或者get存放数据
//caoacity:容量。position:位置,limit:界限
//mark用来标记当前状态。通过reset回到那个状态
//isremaining看看缓冲区是否还有剩余的数据
class test {
	public static void main(String[] args) {
	String s="abcd";
	ByteBuffer byt=ByteBuffer.allocate(1024);
	System.out.println("--allocate--");
	System.out.println(byt.capacity());
	System.out.println(byt.position());
	System.out.println(byt.limit());
	byt.put(s.getBytes());//存放
	System.out.println("--put--");
	System.out.println(byt.capacity());
	System.out.println(byt.position());
	System.out.println(byt.limit());//1024
	byt.flip();//切换读取模式
	System.out.println("--flip--");
	System.out.println(byt.capacity());
	System.out.println(byt.position());//0
	System.out.println(byt.limit());//4
	byte[] bt=new byte[byt.limit()];
	byt.get(bt);//get读取缓冲区
	System.out.println(new String(bt,0,bt.length));
	System.out.println("--get--");
	System.out.println(byt.capacity());
	System.out.println(byt.position());//4
	System.out.println(byt.limit());//4
	byt.rewind();//position归0
	System.out.println("--rewind--");
	System.out.println(byt.capacity());
	System.out.println(byt.position());//0
	System.out.println(byt.limit());//4
	byt.clear();//清空缓存区,但是数据还在。处于被遗忘状态
	System.out.println("--clear--");
	System.out.println(byt.capacity());
	System.out.println(byt.position());//0
	System.out.println(byt.limit());//1024
	
}

}

非直接缓冲区:通过allocate(底层代码在堆内存开辟数组)分配缓冲区,将缓冲区建立在jvm内存中

直接缓冲区:通过allocatedirect(在操作系统上)直接分配,将缓冲区建立在物理内存上,可以挺高效率。不安全,消耗大,写入文件我们管不了

channel通道:源节点与目标节点的连接,channel本身不存储数据,需要配合缓存区存储。

通过getchannel获取通道如

fileoutputstream/fileoutputstream

网络IO

socket/serversocket/datagramsocket

JDK7中NIO2中可以通过open方法或者files类的newbytechannel方法开通道。

//通道直接缓冲区(内存映射文件)
	FileChannel in = FileChannel.open(Paths.get("1.jpg"),StandardOpenOption.READ);
	FileChannel out = FileChannel.open(Paths.get("2.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ);
	//内存映射文件
	MappedByteBuffer map = in.map(MapMode.READ_ONLY, 0, in.size());
	MappedByteBuffer map2 = out.map(MapMode.READ_WRITE, 0,in.size());
	//直接对缓冲区进行读写操作
	byte[] b=new byte[1024];
	map.get(b);
	map2.put(b);
	in.close();
	out.close();
	//通道间数据传输(直接缓冲区)
		FileChannel in = FileChannel.open(Paths.get("1.jpg"),StandardOpenOption.READ);
		FileChannel out = FileChannel.open(Paths.get("2.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ);
		in.transferTo(0, in.size(), out);
		in.close();
		out.close();

阻塞nio读写文件

class client {
	public static void main(String[] args) throws IOException {	

	SocketChannel open = SocketChannel.open(new InetSocketAddress("127.0.0.1", 12345));//打开通道
	FileChannel open2 = FileChannel.open(Paths.get("1.txt"), StandardOpenOption.READ);//打开复制文件通道
	ByteBuffer allocate = ByteBuffer.allocate(1024);//建立缓冲区
	while(open2.read(allocate)!=-1){
		allocate.flip();//打开读取模式
		open.write(allocate);
		allocate.clear();
	}

	open.shutdownOutput();
	//接受服务器端反馈
	int len=0;
	while((len=open.read(allocate))!=-1){
		allocate.flip();
	
		System.out.println(new String(allocate.array(),0,len));
		allocate.clear();
	}

	open2.close();
	open.close();
	}}
class server{
	public static void main(String[] args) throws IOException {
		ServerSocketChannel open = ServerSocketChannel.open();//打开网络通道
		//选择要存储的地方
		FileChannel open2 = FileChannel.open(Paths.get("2.txt"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);
		//与端口号绑定
		open.bind(new InetSocketAddress( 12345));
		SocketChannel accept = open.accept();
		ByteBuffer allocate = ByteBuffer.allocate(1024);
		while(accept.read(allocate)!=-1){
			allocate.flip();
			open2.write(allocate);
			allocate.clear();
		}
		allocate.put("已经收到".getBytes());
		allocate.flip();
		accept.write(allocate);
		
	}
}

利用选择器进行非阻塞NIO


class server{
	public static void main(String[] args) throws IOException {
		ServerSocketChannel open = ServerSocketChannel.open();//打开网络通道
		open.configureBlocking(false);
		//与端口号绑定
		open.bind(new InetSocketAddress(12345));
		//获取选择器
		Selector selector = Selector.open();
		//将通道注册到选择器上
		open.register(selector, SelectionKey.OP_ACCEPT);
		//轮询式获取选择器上准备就绪事件
		while(selector.select()>0){
			//获取当前选择器中所有注册的选择键
			Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
			while(iterator.hasNext()){
				//获取准备就绪的事件
				SelectionKey sk = iterator.next();
				//判断什么事件准备就绪
				if(sk.isAcceptable()){
					//若接受就绪,客户端获取连接
					SocketChannel accept = open.accept();
					//切换非阻塞模式
					accept.configureBlocking(false);
					//将该通道注册到选择器上
					accept.register(selector, SelectionKey.OP_READ);
				}else if(sk.isReadable()){
					//获取读就绪状态的通道
					SocketChannel channel = (SocketChannel)sk.channel();
					//读取数据
					ByteBuffer allocate = ByteBuffer.allocate(1024);
					int len=0;
					while((len=channel.read(allocate))!=-1){
						allocate.flip();
						System.out.printf(new String(allocate.array()),0,len);
						allocate.clear();
					}
				}
			}
		}
		
		}
	
	}
class client {
	public static void main(String[] args) throws IOException {	
		
	SocketChannel open = SocketChannel.open(new InetSocketAddress("127.0.0.1",12345));//打开通道
	open.configureBlocking(false);//切换成非阻塞模式
	
	//分配缓冲区
	ByteBuffer allocate = ByteBuffer.allocate(1024);
	//发送数据
	allocate.put("你好".getBytes());
	allocate.flip();
	open.write(allocate);
	allocate.clear();

	}
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值