`

NIO(十)—— NIO的几个例子

    博客分类:
  • NIO
 
阅读更多

1. FileChannel写入文件

package com.mycom.test.nio;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * FileChannel写入文件
 * 
 * @author guweiqiang
 */
public class TestFileChannelWrite {

	public static void main(String[] args) {
		try {
			// 新建一个File对象
			File file = new File("e:/writeData.txt");
			// 将文件读取到文件输出流中
			FileOutputStream outputStream = new FileOutputStream(file);
			// 获取FileChannel通道对象
			FileChannel fileChannel = outputStream.getChannel();
			// 新建缓冲区
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			String testStr = "hello world!";
			// 将内容写入到缓冲区
			buffer.put(testStr.getBytes());
			buffer.flip(); //此处必须要调用buffer的flip方法
			// 将缓冲区内容写入到fileChannel通道
			fileChannel.write(buffer);
			// 关闭fileChannel通道
			fileChannel.close();
			// 关闭文件输出流
			outputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}		
	}

}

 

 

2. FileChannel读取文件

package com.mycom.test.nio;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * FileChannel读取文件
 * 
 * @author guweiqiang
 */
public class TestFileChannelRead {

	@SuppressWarnings("resource")
	public static void main(String[] args) {
		try {
			// 新建一个RandomAccessFile对象
			RandomAccessFile file = new RandomAccessFile("e:/readData.txt", "rw"); // rw表示以读写方式打开文件,r表示只读方式打开
			// 获取FileChannel通道对象
			FileChannel fileChannel = file.getChannel();
			// 新建缓冲区
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			// 将fileChannel中的数据读取到buffer中
			fileChannel.read(buffer);
			// 再将buffer中的数据读取到String对象中
			byte[] data = buffer.array();
			String ss = new String(data).trim();
			System.out.println(ss);
			// 关闭fileChannel通道
			fileChannel.close();
		} catch (IOException e) {
			e.printStackTrace();
		}		
	}

}

 (前提是存在以下文件:e:/readData.txt

 

 

 3. Server与Cilent通信

NIO 服务端:

package com.mycom.test.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * NIO 服务端
 * 
 * @author guweiqiang
 */
public class NIOServer {
	// 通道管理器
	private Selector selector;
	
	/**
	 * 获取一个服务端通道ServerSocket,并进行初始化
	 */
	public void initServer(int port) throws IOException{
		// 获取一个ServerSocket服务端通道
		ServerSocketChannel serverChannel = ServerSocketChannel.open();
		// 设置通道为非阻塞模式
		serverChannel.configureBlocking(false);
		// 绑定端口
		serverChannel.socket().bind(new InetSocketAddress(port));
		// 获取一个通道管理器
		this.selector = Selector.open();
		// 将通道管理器和通道进行绑定,并为该通道注册SelectionKey.OP_ACCEPT事件
		// 当事件到达时,selector.select()就会返回;如果事件没有到达,则selector.select()就会一直阻塞
		serverChannel.register(selector, SelectionKey.OP_ACCEPT);
	}
	
	/**
	 * 采用轮询的方式监听selector上是否有需要处理的事件,如果有则进行处理
	 */
	@SuppressWarnings("rawtypes")
	public void listen() throws IOException{
		System.out.println("服务端启动成功!");
		
		// 轮询访问selector
		while(true){
			// 当有已注册的事件到达时,方法返回,否则就一直阻塞到有注册的事件到达为止
			selector.select();
			
			// 获取selector中选中项的迭代器,选中项为注册的事件
			Iterator it = this.selector.selectedKeys().iterator();
			while(it.hasNext()){
				SelectionKey key = (SelectionKey)it.next();
				// 删除已选的key,防止重复处理
				it.remove();
				
				if(key.isAcceptable()){ // 有客户端请求连接的事件
					// 获取服务端通道
					ServerSocketChannel serverChannel = (ServerSocketChannel)key.channel();
					// 获取与客户端连接的通道
					SocketChannel clientChannel = serverChannel.accept();
					// 设置为非阻塞
					clientChannel.configureBlocking(false);
					// 给客户端发送消息
					clientChannel.write(ByteBuffer.wrap(new String("hello client, i'm server!").getBytes("utf-8")));
					// 在和客户端连接成功之后,为了可以接收到客户端的消息,需要给通道设置读权限
					clientChannel.register(this.selector, SelectionKey.OP_READ);
					
				} else if(key.isReadable()){ // 有读取事件发生
					readKey(key);
				}
			}
		}
	}

	/**
	 * 处理读取客户端发来的消息
	 */
	private void readKey(SelectionKey key) throws IOException {
		// 服务器可读取消息:得到事件发生的Socket通道 
		SocketChannel channel = (SocketChannel)key.channel();
		
		// 读取通道里的消息
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		channel.read(buffer);
		byte[] data = buffer.array();
		String receivedMsg = new String(data).trim();
		System.out.println("服务端收到客户端发来的的消息:" + receivedMsg);
		
		// 向通道写入消息
		String sendMsg = "hello client!";
		ByteBuffer outBuffer = ByteBuffer.wrap(sendMsg.getBytes("utf-8")); 
		channel.write(outBuffer);// 将消息回送给客户端  
	}
	
	/**
	 * 启动服务端测试
	 */
	public static void main(String[] args) {
		try {
			NIOServer server = new NIOServer();
			server.initServer(8000);
			server.listen();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 NIO 客户端:

package com.mycom.test.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * NIO 客户端
 * 
 * @author guweiqiang
 */
public class NIOClient {
	// 通道管理器
	private Selector selector;
	
	/**
	 * 获取一个客户端通道,并进行初始化
	 * @throws IOException 
	 */
	public void initClient(String ip, int port) throws IOException{
		// 获取一个Socket客户端通道
		SocketChannel clientChannel = SocketChannel.open();
		// 设置通道为非阻塞模式
		clientChannel.configureBlocking(false);
		// 获取一个通道管理器
		this.selector = Selector.open();
		// 客户端连接服务器
		clientChannel.connect(new InetSocketAddress(ip, port));
		// 将通道管理器和通道进行绑定,并为该通道注册SelectionKey.OP_CONNECT事件
		clientChannel.register(selector, SelectionKey.OP_CONNECT);
	}

	/**
	 * 采用轮询的方式监听selector上是否有需要处理的事件,如果有则进行处理
	 */
	@SuppressWarnings("rawtypes")
	public void listen() throws IOException{
		// 轮询访问selector
		while(true){
			// 当有已注册的事件到达时,方法返回,否则就一直阻塞到有注册的事件到达为止
			selector.select();
			
			// 获取selector中选中项的迭代器,选中项为注册的事件
			Iterator it = this.selector.selectedKeys().iterator();
			while(it.hasNext()){
				SelectionKey key = (SelectionKey)it.next();
				// 删除已选的key,防止重复处理
				it.remove();
				
				if(key.isConnectable()){ // 有连接事件发生
					// 获取客户端通道
					SocketChannel clientChannel = (SocketChannel)key.channel();
					// 如果正在连接,则设置连接完成
					if(clientChannel.isConnectionPending()){
						clientChannel.finishConnect();
					}
					// 设置通道为非阻塞模式
					clientChannel.configureBlocking(false);
					// 给服务端发送消息
					clientChannel.write(ByteBuffer.wrap(new String("hello server, i'm client!").getBytes("utf-8")));
					// 在和服务端连接之后,为了可以接收到服务端的消息,需要给客户端设置读权限
					clientChannel.register(selector, SelectionKey.OP_READ);
					
				} else if(key.isReadable()){ // 有读取事件发生
					this.readKey(key);
				}
			}
		}
	}
	
	/**
	 * 处理读取服务端发来的消息
	 */
	private void readKey(SelectionKey key) throws IOException {
		// 服务器可读取消息:得到事件发生的Socket通道 
		SocketChannel channel = (SocketChannel)key.channel();
		
		// 读取通道里的消息
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		channel.read(buffer);
		byte[] data = buffer.array();
		String receivedMsg = new String(data).trim();
		System.out.println("客户端收到服务端发来的消息:" + receivedMsg);
		
		// 向通道写入消息
		String sendMsg = "hello server!";
		ByteBuffer outBuffer = ByteBuffer.wrap(sendMsg.getBytes("utf-8")); 
		channel.write(outBuffer);// 将消息回送给服务端  
	}
	
	/**
	 * 启动客户端测试
	 */
	public static void main(String[] args) {
		try {
			NIOClient client = new NIOClient();
			client.initClient("127.0.0.1", 8000);
			client.listen();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

分享到:
评论

相关推荐

    Java NIO——Java NIO

    Java NIO——Java NIO——Java NIO

    一个java NIO的例子

    Java NIO,全称为Non-Blocking ...这个例子"一个java NIO的例子"是学习和理解Java NIO概念和机制的一个很好的起点。通过分析和运行这个示例,开发者可以更深入地理解Java NIO的工作原理,并能更好地运用到实际项目中。

    Java NIO——Selector机制解析三(源码分析)

    Java NIO,全称为Non-blocking Input/Output,是Java在1.4版本引入的一个新特性,旨在提供一种更高效、更灵活的I/O操作方式。相比于传统的BIO(Blocking I/O),NIO允许我们以非阻塞的方式读写数据,提高了系统资源...

    Java NIO学习笔记——ByteBuffer用法

    在Java编程语言中,NIO(New Input/Output)是一个重要的特性,它为开发者提供了非阻塞I/O操作的能力,极大地提高了程序的性能。本文主要关注的是Java NIO中的ByteBuffer,一个关键的数据容器,用于在通道(Channel)...

    实现java网络与nio例子

    这个例子包含了NIO在网络通信中的应用,包括服务器端(Server)和客户端(Client)的实现。 在Java NIO中,核心组件有通道(Channels)、缓冲区(Buffers)和选择器(Selectors)。通道是数据传输的途径,如套接字...

    JAVA nio的一个简单的例子

    在这个例子中,服务器会读取客户端发送的字符串,计算哈希值,然后将结果写回给客户端。 客户端通常使用SocketChannel与服务器建立连接,并通过该通道发送和接收数据。在发送数据前,需要先将数据写入Buffer,然后...

    自己写的NIO的多播例子

    在Java编程语言中,网络通信是一个重要的领域,而NIO(Non-blocking Input/Output,非阻塞I/O)则是提高程序...通过深入理解和实践这个例子,你可以掌握如何构建自己的多播应用,并理解NIO在多播通信中的作用和优势。

    大数据学习之旅——NIO源码

    NIO与传统的IO模型(-blocking I/O)相比,主要的区别在于它允许单线程处理多个通道(channels),而无需为每个通道创建一个单独的线程。这种方式大大减少了线程创建和销毁带来的开销,对于大数据的处理场景尤其有利...

    NIO 服务器客户端例子

    在这个"NIO 服务器客户端例子"中,`TestServer.java`和`TestClient.java`分别代表服务器端和客户端的实现。 **NIO服务器端(TestServer.java)的关键知识点:** 1. **选择器(Selector)**:服务器通常会创建一个...

    一个NIO服务端,客户端的例子

    这个例子可能包含一个简单的Netty服务器和客户端实现,它们展示了如何利用NIO进行通信。在服务器端,首先会创建一个ServerBootstrap,然后设置通道工厂,通常使用NioServerSocketChannel。接着,配置管道(Pipeline...

    java nio 通信服务器、客户端完整例子

    用java编写的nio通信的例子,nio是io编程的新版本,比io较流行。同时本例子是适用socket通信的。可以在此基础上,添加您的个人应用。本例子适用于:java通信的学习者,android平台通信的学习者。

    java nio socket 例子

    本例包含服务器端和客户端,多线程,每线程多次发送,Eclipse工程,启动服务器使用 nu.javafaq.server.NioServer,启动客户端使用 nu.javafaq.client.NioClient。另本例取自javafaq.nv上的程序修改而成

    javaNiO.doc

    为了解决这些问题,Java平台在JDK 1.4中引入了一个全新的I/O处理框架——NIO(New IO),即新I/O。本文将深入探讨传统I/O模型的问题,并详细介绍NIO的概念、优势以及其实现机制。 #### 2. 传统I/O模型及其局限性 ...

    java NIO.zip

    通道是NIO中的核心概念之一,它提供了从一个数据源(如文件、套接字)到另一个数据源的数据传输路径。Java NIO支持多种类型的通道,包括文件通道(FileChannel)、套接字通道(SocketChannel)和服务器套接字通道...

    JavaNIO chm帮助文档

    Java NIO系列教程(一) Java NIO 概述 Java NIO系列教程(二) Channel ...Java NIO系列教程(十) Java NIO DatagramChannel Java NIO系列教程(十一) Pipe Java NIO系列教程(十二) Java NIO与IO

    nio.rar_NIO_NIO-socket_java nio_java 实例_java.nio

    描述中的“java nio 编程一个实例子.服务端程序”提示我们,这个实例是一个服务器端的应用,它利用Java NIO来处理客户端的连接请求。在NIO服务端编程中,通常会使用`Selector`来监听多个通道的事件,当有新的连接、...

    javaNIO学习笔记(csdn)————程序.pdf

    - **Synchronous Event Demultiplexer(同步事件分离器)**:如Java NIO的Selector,它监听多个通道并通知事件。 - **Initiation Dispatcher(初始分发器)**:Reactor角色,注册、删除事件处理器,并在事件发生时...

    Java NIO英文高清原版

    Netty是一个基于NIO的高性能、异步事件驱动的网络应用框架,它简化了网络编程,广泛应用于服务器端应用开发。 NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。以下是对这些核心概念的...

    基于nio实现的多文件上传源码

    在Java编程领域,NIO(New IO)是一个重要的特性,它是Java 1.4版本引入的,用于替代标准的IO API。NIO提供了一种非阻塞I/O操作的方式,特别适用于处理大量的并发连接,例如在文件传输、网络通信等场景。本主题...

Global site tag (gtag.js) - Google Analytics