通道(Channel):由 java.nio.channels 包定义的。Channel 表示 IO 源与目标打开的连接。Channel 类似于传统的“流”。只不过 Channel 本身不能直接访问数据,Channel 只能与Buffer 进行交互
常用通道类:
•FileChannel:用于读取、写入、映射和操作文件的通道。
•DatagramChannel:通过 UDP 读写网络中的数据通道。
•SocketChannel:通过 TCP 读写网络中的数据。
•ServerSocketChannel:可以监听新进来的 TCP 连接,对每一个新进来
的连接都会创建一个 SocketChannel
通道获取方式:
1.获取通道的一种方式是对支持通道的对象调用getChannel() 方法。支持通道的类如下:
FileInputStream
FileOutputStream
RandomAccessFile
DatagramSocket
Socket
ServerSocket
2.获取通道的其他方式是使用 Files 类的静态方法 newByteChannel() 获取字节通道。
3.通过通道的静态方法 open() 打开并返回指定通道
如FileChannel.open(Path,OpenOption)
package com.jv.nio.buffer;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import org.junit.Test;
public class ChannelTest {
@Test
public void test1() {
long start = System.currentTimeMillis();
FileChannel fis = null;
FileChannel fos = null;
try {
fis = FileChannel.open(Paths.get("e://3.zip"), StandardOpenOption.READ);
fos = FileChannel.open(Paths.get("e://4.zip"), StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE);
fis.transferTo(0, fis.size(), fos);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long end = System.currentTimeMillis();
System.out.println("耗时:"+(end-start));
//53097
}
@Test
public void test2() {
long start = System.currentTimeMillis();
FileChannel fis = null;
FileChannel fos = null;
try {
fis = FileChannel.open(Paths.get("e://3.zip"), StandardOpenOption.READ);
fos = FileChannel.open(Paths.get("e://4.zip"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
MappedByteBuffer in_mb = fis.map(MapMode.READ_ONLY, 0, fis.size());
MappedByteBuffer out_mb = fos.map(MapMode.READ_WRITE, 0, fis.size());
byte[] dst = new byte[in_mb.limit()];
in_mb.get(dst);
out_mb.put(dst);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long end = System.currentTimeMillis();
System.out.println("耗时:"+(end-start));
//15425
}
@Test
public void test3() {
long start = System.currentTimeMillis();
FileChannel fis = null;
FileChannel fos = null;
try {
fis = FileChannel.open(Paths.get("e://3.zip"), StandardOpenOption.READ);
fos = FileChannel.open(Paths.get("e://4.zip"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
//②分配指定大小的缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024);
//③将通道中的数据存入缓冲区中
while(fis.read(buf) != -1){
buf.flip(); //切换读取数据的模式
//④将缓冲区中的数据写入通道中
fos.write(buf);
buf.clear(); //清空缓冲区
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long end = System.currentTimeMillis();
System.out.println("耗时:"+(end-start));
}
}