nio的学习
java中nio的核心是通道和缓冲区,它与IO的区别是面 向缓冲区,非阻塞IO,有选择器。
缓冲区负责数据存取,缓冲区就是数组。根据数据类型不同(boolean除外),提供相应类型缓冲区。
缓冲区四个核心属性:
capacity:容量,表示缓冲区中最大存储数据人的容量,一旦声明不能改变。
limit:界限,缓冲区中可以操作数据的大小
position:位置,表示缓冲区中正在操作数据的位置
mark:标记,记录当前positon位置,可以通过reset()恢复到mark位置。
分配缓冲区大小:allocate(num)
ByteBuffer buf = ByteBuffer.allocate(1024);//分配大小
存入缓冲区数据put()
buf.put("abc".getBytes());
获取缓冲区数据get()
buf.flip();//切换到读模式positon和limit会改变为缓冲区大小 but.get(byte[]);
重复读数据rewind();
清空缓冲区clear();
直接缓冲区:通过allocateDirect()方法直接在主内存中建立缓冲区。
非直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立在jvm的内存中
通道:用于源与目标节点的连接,负责缓冲区中数据的传输。
通道有FileChannel、SocketChannel、等,getChannel()方法获取通道。针对通道提供了open(),
非直接缓冲区复制文件
FileInputStream fis = new FileInputStream("a.jpg"); FileOutStream fos = new FileOutputStream("b.jpg"); //获取通道 FileChannel inChannel = fis.getChannel(); FileChannel outChannel = fos.getChannel(); //分配缓冲区大小 ByteBuffer buf = ByteBuffer.allocate(1024); //将通道中的数据写入缓冲区 while(inChannel.read(buf)!=-1){ buf.flip();//切换读取模式 outChannel.write(buf);//将缓冲区中的数据写入通道 buf.clear();//清空缓冲区 } outChannel.close(); inChannel.close(); fis.close(); fos.close();
直接缓冲区文件复制
FileChannel in = FileChannel.open(Paths.get("a.jpg"),StandardOpenOption.READ); FileChannel out = FileChannel.open(Paths.get("b.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW); //内存映射文件 MappedByteBuffer inMappedBuf = in.map(MapMode.READ_ONLY,0,in.size()); MappedByteBuffer outMappedBuf = out.map(MapMode.READ_WRITE,0,in.size()); //直接对缓冲区进行数据的读写操作 byte[] dst = new byte[inMappedBuf.limit()]; inMappedBuf.get(dst); outMappedBuf.put(dst); in.close(); out.close();
通道间的数据传输
FileChannel in = FileChannel.open(Paths.get("a.jpg"),StandardOpenOption.READ); FileChannel out = FileChannel.open(Paths.get("b.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW); in.transferTo(0,in.size(),out);
//out.transferFrom(0,in.size(),in);
in.close(); out.close();
Scatter(分散):将通道中的数据分散到多Buffer中去。
RandomAccessFile raf1 = new RandomAccessFile("1.txt","rw"); //获取通道 FileChannel channel1 =raf1.getChannel(); //分配指定大小缓冲区 ByteBuffer buf1 = ByteBuffer.allocate(100); ByteBuffer buf2 = ByteBuffer.allocate(1024); //分散读取 ByteBuffer[] bufs = {buf1,buf2}; channel1.read(bufs); for(ByteBuffer byteBuffer:bufs){ byteBuffer.flip(); } //聚集写入 RandomAccessFile raf2 = new RandomAccessFile("2.txt","rw"); //获取通道 FileChannel channel2 =raf2.getChannel(); channel2.write(bufs);
编码:
Charset.availableCharsets();
Charset cs = Charset.forName("GBK"); //获取编码器 CharsetEncoder ce = cs1.newEncoder(); //获取解码器 CharsetDecoder cd = cs1.newDecoder(); CharBuffer cBuf = CharBuffer.allocate(1024); cBuf.put("这是测试"); cBuf.flip(); //编码 ByteBuffer bBuf =ce.encode(cBuf); //解码 bBuf.flip(); CharBuffer cBuf2 = cd.decode(dBuf);
Gather(聚集):
...