一、通道(Channel): 用于源节点与目标节点的连接。在java NIO中负责缓冲区中数据的传输。Channel本身不存储数据,因此需要配合缓冲区进行传输。
二、通道的主要实现类
java.nio.channels.Channel接口:
|– FileChannel
|– SocketChannel
|– ServerSocketChannel
|– DatagramChannel
三、获取通道
1、java针对支持通道的类提供了getChannel()方法
本地IO:
FileInputStream/FileOutputStream
RandomAccessFile
网络IO:
Socket
ServerSocket
DatagramSocket
2、在jdk1.7中NIO.2针对各个通道提供了静态方法open()
3、在jdk1.7中NIO.2的Files工具类的newByteChannel()
@Test //利用通道完成文件复制
public void test4() throws FileNotFoundException{
FileInputStream fis = new FileInputStream("1.mp4");
FileOutputStream fos=new FileOutputStream("2.mp4");
//1、获取通道
FileChannel inChannel = fis.getChannel();
FileChannel outChannel = fos.getChannel();
try {
//2、分配一个指定大小的缓冲区
ByteBuffer buf=ByteBuffer.allocate(1024);
//3、将通道中的数据存入缓冲区
while(inChannel.read(buf)!=-1){
//4、将缓冲区中的数据写入通道中
buf.flip(); //切换读取数据模式
outChannel.write(buf);
buf.clear();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
outChannel.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test //使用直接缓冲区完成文件的复制
public void test5() throws IOException{
FileChannel inChannel=FileChannel.open(Paths.get("1.mp4"),StandardOpenOption.READ);
FileChannel outChannel=FileChannel.open(Paths.get("2.mp4"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
//内存映射文件
MappedByteBuffer inMappedBuf=inChannel.map(MapMode.READ_ONLY,0,inChannel.size());
MappedByteBuffer outMappedBuf=outChannel.map(MapMode.READ_WRITE,0,inChannel.size());
//直接对缓冲区进行数据的读写操作
byte[] dst=new byte[inMappedBuf.limit()];
inMappedBuf.get(dst);
outMappedBuf.put(dst);
outChannel.close();
inChannel.close();
}
四、通道之间的数据传输
@Test // 通道之间的数据传输(直接缓冲区)
public void test6() throws IOException{
FileChannel inChannel=FileChannel.open(Paths.get("1.mp4"),StandardOpenOption.READ);
FileChannel outChannel=FileChannel.open(Paths.get("2.mp4"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
//inChannel.transferTo(0,inChannel.size(),outChannel); //二选一即可
outChannel.transferFrom(inChannel,0,inChannel.size());
outChannel.close();
inChannel.close();
}