NIO简单应用
使用FileChannel完成文件复制
public class FileNIOCopyDemo {
public static void main(String[] args) {
nioCopyResourceFile();
}
/**
* 复制两个资源目录下的文件
*/
private static void nioCopyResourceFile() {
String sourcePath = NioDemoConfig.sourcePath;
String destPath = NioDemoConfig.destPath;
nioCopyFile(sourcePath, destPath);
}
private static void nioCopyFile(String sourcePath, String destPath) {
File srcFile = new File(sourcePath);
File destFile = new File(destPath);
try {
if (!destFile.exists()) {
destFile.createNewFile();
}
long startTime = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(destFile);
inChannel = fis.getChannel();
outChannel = fos.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int length = 0;
int outlength = 0;
//从读通道读取数据到buffer
while ((length = inChannel.read(buffer)) != -1) {
//切换buffer至读模式
buffer.flip();
//将buffer内容写入输出channel
while ((outlength = outChannel.write(buffer)) != 0) {
System.out.println("写入的字节数: " + outlength);
}
//切换buffer为写模式
buffer.clear();
}
//强制刷新到磁盘
outChannel.force(true);
} finally {
closeUtil(outChannel);
closeUtil(inChannel);
closeUtil(fos);
closeUtil(fis);
Long endTime = System.currentTimeMillis();
System.out.println("复制花费毫秒数: " + (endTime - startTime));
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void closeUtil(Closeable item) {
if (item != null) {
try {
item.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用SocketChannel发送文件
客户端发送
public class NioSendClient {
private Charset charset = Charset.forName("UTF-8");
public static void main(String[] args) {
NioSendClient client = new NioSendClient();//启动客户端连接
client.sendFile();//传输文件
}
/**
* 向服务器传输文件
*/
private void sendFile() {
try {
//获取源文件、目的文件路径
String srcPath = NioDemoConfig.sourcePath;
String destPath = NioDemoConfig.destPath;
//获取源文件File对象
File srcFile = new File(srcPath);
if (!srcFile.exists()) {
System.out.println("文件不存在");
return;
}
//获取源文件流
FileInputStream fileInputStream = new FileInputStream(srcFile);
//获取源文件通道
FileChannel fileChannel = fileInputStream.getChannel();
//获取Socket通道
SocketChannel socketChannel = SocketChannel.open();
//连接服务端
socketChannel.connect(new InetSocketAddress(NioDemoConfig.SOCKET_SERVER_IP, NioDemoConfig.SOCKET_SERVER_PORT));
//设置channel为非阻塞
socketChannel.configureBlocking(false);
//自旋,等待连接完成
while (!socketChannel.finishConnect()) {
//不断自旋、等待,或者做一些其他操作
}
System.out.println("Client成功连接服务器端");
//发送文件名称
ByteBuffer fileNameByteBuffer = charset.encode(destPath);
socketChannel.write(fileNameByteBuffer);
//发送文件长度
ByteBuffer buffer = ByteBuffer.allocate(NioDemoConfig.SEND_BUFFER_SIZE);
buffer.putLong(srcFile.length());
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
//发送文件内容
System.out.println("开始传输文件");
int length = 0;
long progress = 0;
while ((length = fileChannel.read(buffer)) > 0) {
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
progress += length;
System.out.println("| " + (100 * progress / srcFile.length()) + "% |");
}
//判断文件传输结束,发送结束符至对端
if (length == -1) {
closeUtil(fileChannel);
//在SocketChannel传输通道关闭前,尽量发送一个输出结果标志到对端
socketChannel.shutdownOutput();
closeUtil(socketChannel);
}
System.out.println("====== 文件传输成功 =======");
} catch (Exception e) {
e.printStackTrace();
}
}
private static void closeUtil(Closeable item) {
if (item != null) {
try {
item.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用DatagramChannel数据报通道发送数据
客户端
public class UDPClient {
public static void main(String[] args) throws IOException {
new UDPClient().send();
}
public void send() throws IOException {
//获取DatagramChannel数据报通道
DatagramChannel channel = DatagramChannel.open();
//设置为非阻塞
channel.configureBlocking(false);
//创建ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(NioDemoConfig.SEND_BUFFER_SIZE);
//扫描输入
Scanner scanner = new Scanner(System.in);
//遍历扫描到的内容,发送数据
while (scanner.hasNext()) {
String next = scanner.next();
buffer.put(next.getBytes());
channel.send(buffer, new InetSocketAddress(NioDemoConfig.SOCKET_SERVER_IP, NioDemoConfig.SOCKET_SERVER_PORT));
buffer.clear();
}
//关闭数据报通道
channel.close();
}
}
服务端
public class UDPServer {
public static void main(String[] args) throws IOException {
new UDPServer().receive();
}
public void receive() throws IOException {
//获取数据报通道
DatagramChannel channel = DatagramChannel.open();
//设置为非阻塞
channel.configureBlocking(false);
//绑定监听地址
channel.socket().bind(new InetSocketAddress(NioDemoConfig.SOCKET_SERVER_IP, NioDemoConfig.SOCKET_SERVER_PORT));
//开启一个通道选择器
Selector selector = Selector.open();
//将通道注册到选择器
channel.register(selector, SelectionKey.OP_READ);
//通过选择器,查询IO事件
while (selector.select() > 0) {
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
ByteBuffer buffer = ByteBuffer.allocate(NioDemoConfig.SEND_BUFFER_SIZE);
//迭代IO事件
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
//可读事件,有事件到来
if (selectionKey.isReadable()) {
//读取数据报通道的数据
SocketAddress client = channel.receive(buffer);
buffer.flip();
System.out.println(new String(buffer.array(), 0, buffer.limit()));
buffer.clear();
}
}
iterator.remove();
}
}
}
参考资料:《Netty、Redis、Zookeeper高并发实战》