1、通道:用于源节点与目的节点的连接。在Java NIO中负责缓冲区中数据的传输。通道本身不存储数据,因此需要配合缓冲区进行传输。Channel 只能与Buffer 进行交互 。
2、通道的主要实现类
FileChannel:用于读取、写入、映射和操作文件的通道。
DatagramChannel:通过 UDP 读写网络中的数据通道。
SocketChannel:通过 TCP 读写网络中的数据。
ServerSocketChannel:可以监听新进来的 TCP 连接,对每一个新进来的连接都会创建一个 SocketChannel。
3、获取通道
①针对支持通道的对象调用getChannel() 方法。支持通道的类如下:
本地IO:
FileInputStream
FileOutputStream
RandomAccessFile
网络IO:
DatagramSocket
Socket
ServerSocket
②在jdk1.7中的NIO中针对各个通道提供了静态方法open()打开并返回指定通道
③在jdk1.7中的NIO中Files工具类的newByteChannel() 获取字节通道。
/**
* 使用直接缓冲区
* @throws IOException
*/
@Test
public void testChannel2() throws IOException{
FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("3.jpg"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
//内存映射文件
MappedByteBuffer inMappedByteBuffer = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
MappedByteBuffer outMappedByteBuffer = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
byte[] des = new byte[inMappedByteBuffer.limit()];
inMappedByteBuffer.get(des);
outMappedByteBuffer.put(des);
inChannel.close();
outChannel.close();
}
/**
* 使用非直接缓冲区
*/
@Test
public void testChannel(){
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
FileChannel fileinChannel = null;
FileChannel fileoutChannel = null;
try {
fileInputStream = new FileInputStream("1.jpg");
fileOutputStream = new FileOutputStream("2.jpg");
//获取通道
fileinChannel = fileInputStream.getChannel();
fileoutChannel = fileOutputStream.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
//将通道中的数据存入缓冲区
while(fileinChannel.read(byteBuffer) != -1){
byteBuffer.flip();//读取模式
//将缓冲区数据写入通道
fileoutChannel.write(byteBuffer);
byteBuffer.clear();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if (fileinChannel != null){
try {
fileinChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fileoutChannel !=null){
try {
fileoutChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fileInputStream != null){
try {
fileInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fileOutputStream != null){
try {
fileOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
4、通道之间的数据传输
transferForm()
transferTo()
/**
* 使用直接缓冲区
* @throws IOException
*/
@Test
public void testChannel3() throws IOException{
FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("4.jpg"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
inChannel.transferTo(0, inChannel.size(), outChannel);
inChannel.close();
outChannel.close();
}