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(聚集):
...
浙公网安备 33010602011771号