目录
目录
FileChannel
读取文件
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class Main {
public static void main(String[] args) throws IOException {
// 获取文件,"r"为只读模式
RandomAccessFile file = new RandomAccessFile("D:/data/data.txt", "r");
// 获取文件通道
FileChannel channel = file.getChannel();
// 分配一个容量为1024的字节缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
// 循环从通道中读取内容到字节缓冲区
while (channel.read(byteBuffer) != -1) {
// 将字节缓冲区的position置为0,limit置为position,也就是将缓冲区由读入模式切换为写出模式,以便后面的get()进行数据取出
byteBuffer.flip();
// 检查在当前的position->limit之间,是否存在剩余元素
while (byteBuffer.hasRemaining())
// 如果存在,取出
System.out.print((char) byteBuffer.get());
// 清空已读取的数据
byteBuffer.compact();
}
channel.close();
file.close();
}
}
写入文件
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class Main {
public static void main(String[] args) throws IOException {
// 获取文件,"rw"为读写模式
RandomAccessFile file = new RandomAccessFile("D:/data/data.txt", "rw");
// 获取文件通道
FileChannel channel = file.getChannel();
// 分配一个容量为1024的字节缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
// 循环从通道中读取内容到字节缓冲区
byteBuffer.put("hello".getBytes());
//将字节缓冲区的position置为0,limit置为position,也就是将缓冲区由读入模式切换为写出模式。
byteBuffer.flip();
// 写出
channel.write(byteBuffer);
channel.close();
file.close();
}
}
SocketChannel
对于SocketChannel的数据读写,方式与FileChannel文件数据读写一样,区别在于获取通道的方式:
SocketAddress address = new InetSocketAddress("vm01", 9999);
SocketChannel channel = SocketChannel.open(address);
ServerSocketChannel和Selector
可使用选择器(Selector),对ServerSocketChannel进行注册,以下代码模拟了客户端和服务端,客户端输入字符串,服务端会接到请求并打印到console,先启动server。
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
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.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Set;
public class Server {
public static void main(String[] args) {
Server server = new Server();
try {
server.run();
} catch (IOException e) {
e.printStackTrace();
}
}
private ServerSocketChannel channel;
private Selector selector;
private int capacity;
public void run() throws IOException {
init();
while (true) {
selector.select();
Set<SelectionKey> keySet = selector.selectedKeys();
Iterator<SelectionKey> iterator = keySet.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
iterator.remove();
// 监听链接事件
if (selectionKey.isAcceptable()) {
handleAcceptable(selector, channel);
} else if (selectionKey.isReadable()) {
handleReadable(selectionKey);
}
}
}
}
/**
* 初始化ServerSocketChannel和selector,并注册
*
* @throws IOException
*/
private void init() throws IOException {
// 获取通道
channel = ServerSocketChannel.open();
SocketAddress address = new InetSocketAddress("127.0.0.1", 8888);
// 绑定通道地址
channel.bind(address);
// 设置通道为非阻塞
channel.configureBlocking(false);
// 打开选择器
selector = Selector.open();
// 通道注册
channel.register(selector, SelectionKey.OP_ACCEPT);
}
/**
* 处理链接事件
*
* @param selector 选择器
* @param channel 通道
* @throws IOException
*/
private void handleAcceptable(Selector selector, ServerSocketChannel channel) throws IOException {
SocketChannel socketChannel = channel.accept();
socketChannel.configureBlocking(false);
// 注册可读事件
socketChannel.register(selector, SelectionKey.OP_READ);
}
/**
* 处理可读事件
*
* @param selectionKey 选择键
* @throws IOException
*/
private void handleReadable(SelectionKey selectionKey) throws IOException {
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(capacity);
StringBuilder builder = new StringBuilder();
while (socketChannel.read(readBuffer) > 0) {
readBuffer.flip();
builder.append(StandardCharsets.UTF_8.decode(readBuffer));
}
if (builder.length() > 0) {
System.out.println(builder);
}
// 继续注册可读事件
// socketChannel.register(selector, SelectionKey.OP_READ);
}
}
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws IOException, InterruptedException {
SocketAddress address = new InetSocketAddress("127.0.0.1", 8888);
SocketChannel channel = SocketChannel.open(address);
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (!"".equals(line) && line != null) {
Thread.sleep(2000);
channel.write(StandardCharsets.UTF_8.encode(line));
}
}
channel.close();
}
}