java nio channel
Java NIO 通道类似于流,但又有一下不同:
1、既可以从通道中读取数据,也可以写数据到通道中。java .io 中的流是单向性。
2、通道数据读取可以异步。
3、通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。
总结:从通道中读取数据到Buffer缓存中,从Buffer缓存中写入数据到通道中。如下截图所示:
Java NIO 通道详解:
1、FileChannel:文件中读写数据
2、DatagramChannel:通过UDP 读写网络数据
3、SocketChannel:通过TCP 读写网络数据
4、ServerSocketChannel:监听新进来的TCP 连接,像Web 服务器那样。对每一个新进来的连接都会创建一个socketchannel.
示列一:文件拷贝功能(基于FileChannel)
package com.nio.filechannel;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class CopyFile {
public static boolean copy(String in,String out){
boolean target = false;
try {
//文件输入流
FileInputStream inStream = new FileInputStream(new File(in));
//文件输出流
FileOutputStream outStream = new FileOutputStream(new File(out));
//文件输入通道
FileChannel inChannel =inStream.getChannel();
//文件输出通道
FileChannel outChannel=outStream.getChannel();
//文件缓存大小1024字节
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(true){
//clear方法重置缓存区,接收读入数据
buffer.clear();
//从输入通道将数据读到缓存区
int result = inChannel.read(buffer);
//判断该输入通道是否读取输入流完毕,如果为-1,表示数据流已经读取完毕,应该终止whil 循环
if(result == -1){
target = true;
break;
}
//数据模式切换(读取模式--------输出模式)
buffer.flip();
//从输出通道将数据写到缓存区
outChannel.write(buffer);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("指定文件名称不存在");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("IO 异常");
e.printStackTrace();
}
return target;
}
public static void main(String[] args){
boolean target = copy("D:\\eula.1028.txt","D:\\a.txt");
if(target){
System.out.println("文件copy 成功");
}else{
System.out.println("文件copy 失败");
}
}
}
示列二:UDP数据发送功能(基于DatagramChannel)
package com.nio.channel;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.charset.Charset;
public class UDPServer {
public static void main(String[] args) {
try {
// 打开数据包通道
DatagramChannel channel = DatagramChannel.open();
// 获取与此通道关联的数据报套接字
channel.socket().bind(new InetSocketAddress(8888));
// 分配一个新的字节缓冲区。
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 判断数据包通道中是否存在数据
while (channel.receive(buffer) == null) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//反转此缓冲区(写模式---读模式)
buffer.flip();
//接受字符
String recStr =Charset.forName("UTF-8").newDecoder().decode(buffer).toString();
System.out.println(recStr);
channel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.nio.channel;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
public class UDPClient {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {// 打开数据包通道
DatagramChannel channel = DatagramChannel.open();
// 将 byte 数组写入缓冲区中
ByteBuffer buffer = ByteBuffer.wrap("左青龙右白虎,南朱雀北玄武".getBytes("UTF-8"));
// 绑定与服务UDP通道关联的数据报套接字
channel.send(buffer, new InetSocketAddress("127.0.0.1", 8888));
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
还没有评论,来说两句吧...