一、通道(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()
*
* 四、通道之间的数据传输
* transferFrom()
* transferTo()
*
* 五、分散(Scatter)与聚集(Gather)
* 分散读取(Scattering Reads):将通道中的数据分散到多个缓冲区中
* 聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到通道中
*
* 六、字符集 : Charset
* 编码:字符串 -> 字节数组 (将看的懂的转为看不懂的为编码)
* 在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()
*
* 四、通道之间的数据传输
* transferFrom()
* transferTo()
*
* 五、分散(Scatter)与聚集(Gather)
* 分散读取(Scattering Reads):将通道中的数据分散到多个缓冲区中
* 聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到通道中
*
* 六、字符集 : Charset
* 编码:字符串 -> 字节数组 (将看的懂的转为看不懂的为编码)
* 解码:字节数组 -> 字符串 (将看不懂的转为看的懂的为解码)
//利用通道完成文件的复制(非直接缓冲区)
@Test
public void test1() throws IOException{
FileInputStream fileInputStream = new FileInputStream("Java.pdf");
FileOutputStream fileOutputStream = new FileOutputStream("JavaCopy.pdf");
FileChannel inChannel = fileInputStream.getChannel();
FileChannel outChannel = fileOutputStream.getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024); //分配一个直接缓冲区
while((inChannel.read(buf))!=-1){
buf.flip(); //切换到读取数据模式
outChannel.write(buf);
buf.clear();
}
outChannel.close();
inChannel.close();
fileOutputStream.close();
fileInputStream.close();
}
//使用直接缓冲区完成文件的复制
@Test
public void test2() throws IOException{
//建立通道
FileChannel incChannel = FileChannel.open(Paths.get("Java.pdf"),StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("JavaCopy.pdf"),StandardOpenOption.WRITE,
StandardOpenOption.READ,StandardOpenOption.CREATE);
//内存映射文件
MappedByteBuffer inMappedByteBuffer = incChannel.map(FileChannel.MapMode.READ_ONLY,0,incChannel.size());
MappedByteBuffer outMappedByteBuffer = outChannel.map(FileChannel.MapMode.READ_WRITE,0,incChannel.size());
//直接对缓冲区进行数据的读写操作
byte[] dst = new byte[inMappedByteBuffer.limit()];
inMappedByteBuffer.get(dst);
outMappedByteBuffer.put(dst);
outChannel.close();
incChannel.close();
}
//通道之间的传输(直接缓冲区)
@Test
public void test3() throws IOException{
//建立通道
FileChannel inChannel = FileChannel.open(Paths.get("Java.pdf"),StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("JavaCopy.pdf"),StandardOpenOption.READ,
StandardOpenOption.WRITE,StandardOpenOption.CREATE);
inChannel.transferTo(0,inChannel.size(),outChannel);
//outChannel.transferFrom(inChannel,0,inChannel.size());
outChannel.close();
inChannel.close();
}
//分散与聚集
@Test
public void test4() throws IOException{
RandomAccessFile rsf1 = new RandomAccessFile("Java.pdf","rw");
//1.获取通道
FileChannel channel1 = rsf1.getChannel();
//2.分配指定大小的缓冲区
ByteBuffer buf1 = ByteBuffer.allocate(100);
ByteBuffer buf2 = ByteBuffer.allocate(1024);
//3.分散读取
ByteBuffer[] dsts = {buf1,buf2};
channel1.read(dsts);
for (ByteBuffer byteBuffer : dsts) {
byteBuffer.flip();
}
System.out.println(new String(dsts[0].array(),0,dsts[0].limit()));
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println(new String(dsts[1].array(),0,dsts[1].limit()));
RandomAccessFile rsf2 = new RandomAccessFile("JavaCopy.pdf","rw");
FileChannel channel2 = rsf2.getChannel();
channel2.write(dsts);
}
//获取编码集
@Test
public void test5(){
SortedMap<String,Charset> sdm = Charset.availableCharsets();
Set<Entry<String,Charset>> set = sdm.entrySet();
for (Entry<String, Charset> entry : set) {
System.out.println(entry.getKey()+"~~~"+entry.getValue());
}
}
//字符集
@Test
public void test6() throws CharacterCodingException{
Charset cs1 = Charset.forName("GBK");
CharsetEncoder ce = cs1.newEncoder(); //获取编码器
CharsetDecoder cd = cs1.newDecoder(); //获取解码器
CharBuffer cbuf = CharBuffer.allocate(1024);
cbuf.put("测试编码");
cbuf.flip();
ByteBuffer buffer = ce.encode(cbuf);
//解码
CharBuffer cBuf2 = cd.decode(buffer);
System.out.println(cBuf2.toString());
}