博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NIO----1
阅读量:5221 次
发布时间:2019-06-14

本文共 10631 字,大约阅读时间需要 35 分钟。

package com.atguigu.nio;import java.nio.ByteBuffer;import org.junit.Test;/* * 一、缓冲区(Buffer):在 Java NIO 中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据 *  * 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区: * ByteBuffer * CharBuffer * ShortBuffer * IntBuffer * LongBuffer * FloatBuffer * DoubleBuffer *  * 上述缓冲区的管理方式几乎一致,通过 allocate() 获取缓冲区 *  * 二、缓冲区存取数据的两个核心方法: * put() : 存入数据到缓冲区中 * get() : 获取缓冲区中的数据 *  * 三、缓冲区中的四个核心属性: * capacity : 容量,表示缓冲区中最大存储数据的容量。一旦声明不能改变。 * limit : 界限,表示缓冲区中可以操作数据的大小。(limit 后数据不能进行读写) * position : 位置,表示缓冲区中正在操作数据的位置。 *  * mark : 标记,表示记录当前 position 的位置。可以通过 reset() 恢复到 mark 的位置 *  * 0 <= mark <= position <= limit <= capacity *  * 四、直接缓冲区与非直接缓冲区: * 非直接缓冲区:通过 allocate() 方法分配缓冲区,将缓冲区建立在 JVM 的内存中 * 直接缓冲区:通过 allocateDirect() 方法分配直接缓冲区,将缓冲区建立在物理内存中。可以提高效率 */public class TestBuffer {        @Test    public void test3(){        //分配直接缓冲区        ByteBuffer buf = ByteBuffer.allocateDirect(1024);                System.out.println(buf.isDirect());    }        @Test    public void test2(){        String str = "abcde";                ByteBuffer buf = ByteBuffer.allocate(1024);                buf.put(str.getBytes());                buf.flip();                byte[] dst = new byte[buf.limit()];        buf.get(dst, 0, 2);        System.out.println(new String(dst, 0, 2));        System.out.println(buf.position());                //mark() : 标记        buf.mark();                buf.get(dst, 2, 2);        System.out.println(new String(dst, 2, 2));        System.out.println(buf.position());                //reset() : 恢复到 mark 的位置        buf.reset();        System.out.println(buf.position());                //判断缓冲区中是否还有剩余数据        if(buf.hasRemaining()){                        //获取缓冲区中可以操作的数量            System.out.println(buf.remaining());        }    }        @Test    public void test1(){        String str = "abcde";                //1. 分配一个指定大小的缓冲区        ByteBuffer buf = ByteBuffer.allocate(1024);                System.out.println("-----------------allocate()----------------");        System.out.println(buf.position());        System.out.println(buf.limit());        System.out.println(buf.capacity());                //2. 利用 put() 存入数据到缓冲区中        buf.put(str.getBytes());                System.out.println("-----------------put()----------------");        System.out.println(buf.position());        System.out.println(buf.limit());        System.out.println(buf.capacity());                //3. 切换读取数据模式        buf.flip();                System.out.println("-----------------flip()----------------");        System.out.println(buf.position());        System.out.println(buf.limit());        System.out.println(buf.capacity());                //4. 利用 get() 读取缓冲区中的数据        byte[] dst = new byte[buf.limit()];        buf.get(dst);        System.out.println(new String(dst, 0, dst.length));                System.out.println("-----------------get()----------------");        System.out.println(buf.position());        System.out.println(buf.limit());        System.out.println(buf.capacity());                //5. rewind() : 可重复读        buf.rewind();                System.out.println("-----------------rewind()----------------");        System.out.println(buf.position());        System.out.println(buf.limit());        System.out.println(buf.capacity());                //6. clear() : 清空缓冲区. 但是缓冲区中的数据依然存在,但是处于“被遗忘”状态        buf.clear();                System.out.println("-----------------clear()----------------");        System.out.println(buf.position());        System.out.println(buf.limit());        System.out.println(buf.capacity());                System.out.println((char)buf.get());            }}

 

 

package com.atguigu.nio;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.RandomAccessFile;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;import java.nio.channels.FileChannel.MapMode;import java.nio.charset.CharacterCodingException;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;import java.nio.charset.CharsetEncoder;import java.nio.file.Paths;import java.nio.file.StandardOpenOption;import java.util.Map;import java.util.Map.Entry;import java.util.Set;import org.junit.Test;/* * 一、通道(Channel):用于源节点与目标节点的连接。在 Java NIO 中负责缓冲区中数据的传输。Channel 本身不存储数据,因此需要配合缓冲区进行传输。 *  * 二、通道的主要实现类 *     java.nio.channels.Channel 接口: *         |--FileChannel *         |--SocketChannel *         |--ServerSocketChannel *         |--DatagramChannel *  * 三、获取通道 * 1. Java 针对支持通道的类提供了 getChannel() 方法 *         本地 IO: *         FileInputStream/FileOutputStream *         RandomAccessFile *  *         网络IO: *         Socket *         ServerSocket *         DatagramSocket *          * 2. 在 JDK 1.7 中的 NIO.2 针对各个通道提供了静态方法 open() * 3. 在 JDK 1.7 中的 NIO.2 的 Files 工具类的 newByteChannel() *  * 四、通道之间的数据传输 * transferFrom() * transferTo() *  * 五、分散(Scatter)与聚集(Gather) * 分散读取(Scattering Reads):将通道中的数据分散到多个缓冲区中 * 聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到通道中 *  * 六、字符集:Charset * 编码:字符串 -> 字节数组 * 解码:字节数组  -> 字符串 *  */public class TestChannel {        //字符集    @Test    public void test6() throws IOException{        Charset cs1 = 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);                for (int i = 0; i < 12; i++) {            System.out.println(bBuf.get());        }                //解码        bBuf.flip();        CharBuffer cBuf2 = cd.decode(bBuf);        System.out.println(cBuf2.toString());                System.out.println("------------------------------------------------------");                Charset cs2 = Charset.forName("GBK");        bBuf.flip();        CharBuffer cBuf3 = cs2.decode(bBuf);        System.out.println(cBuf3.toString());    }        @Test    public void test5(){        Map
map = Charset.availableCharsets(); Set
> set = map.entrySet(); for (Entry
entry : set) { System.out.println(entry.getKey() + "=" + entry.getValue()); } } //分散和聚集 @Test public void test4() throws IOException{ RandomAccessFile raf1 = new RandomAccessFile("1.txt", "rw"); //1. 获取通道 FileChannel channel1 = raf1.getChannel(); //2. 分配指定大小的缓冲区 ByteBuffer buf1 = ByteBuffer.allocate(100); ByteBuffer buf2 = ByteBuffer.allocate(1024); //3. 分散读取 ByteBuffer[] bufs = {buf1, buf2}; channel1.read(bufs); for (ByteBuffer byteBuffer : bufs) { byteBuffer.flip(); } System.out.println(new String(bufs[0].array(), 0, bufs[0].limit())); System.out.println("-----------------"); System.out.println(new String(bufs[1].array(), 0, bufs[1].limit())); //4. 聚集写入 RandomAccessFile raf2 = new RandomAccessFile("2.txt", "rw"); FileChannel channel2 = raf2.getChannel(); channel2.write(bufs); } //通道之间的数据传输(直接缓冲区) @Test public void test3() throws IOException{ FileChannel inChannel = FileChannel.open(Paths.get("d:/1.mkv"), StandardOpenOption.READ); FileChannel outChannel = FileChannel.open(Paths.get("d:/2.mkv"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE); // inChannel.transferTo(0, inChannel.size(), outChannel); outChannel.transferFrom(inChannel, 0, inChannel.size()); inChannel.close(); outChannel.close(); } //使用直接缓冲区完成文件的复制(内存映射文件) @Test public void test2() throws IOException{
//2127-1902-1777 long start = System.currentTimeMillis(); FileChannel inChannel = FileChannel.open(Paths.get("d:/1.mkv"), StandardOpenOption.READ); FileChannel outChannel = FileChannel.open(Paths.get("d:/2.mkv"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE); //内存映射文件 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); inChannel.close(); outChannel.close(); long end = System.currentTimeMillis(); System.out.println("耗费时间为:" + (end - start)); } //利用通道完成文件的复制(非直接缓冲区) @Test public void test1(){
//10874-10953 long start = System.currentTimeMillis(); FileInputStream fis = null; FileOutputStream fos = null; //①获取通道 FileChannel inChannel = null; FileChannel outChannel = null; try { fis = new FileInputStream("d:/1.mkv"); fos = new FileOutputStream("d:/2.mkv"); inChannel = fis.getChannel(); outChannel = fos.getChannel(); //②分配指定大小的缓冲区 ByteBuffer buf = ByteBuffer.allocate(1024); //③将通道中的数据存入缓冲区中 while(inChannel.read(buf) != -1){ buf.flip(); //切换读取数据的模式 //④将缓冲区中的数据写入通道中 outChannel.write(buf); buf.clear(); //清空缓冲区 } } catch (IOException e) { e.printStackTrace(); } finally { if(outChannel != null){ try { outChannel.close(); } catch (IOException e) { e.printStackTrace(); } } if(inChannel != null){ try { inChannel.close(); } catch (IOException e) { e.printStackTrace(); } } if(fos != null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if(fis != null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } long end = System.currentTimeMillis(); System.out.println("耗费时间为:" + (end - start)); }}

 

转载于:https://www.cnblogs.com/hzzhero/p/6942412.html

你可能感兴趣的文章
303. Range Sum Query - Immutable
查看>>
图片加载失败显示默认图片占位符
查看>>
【★】浅谈计算机与随机数
查看>>
《代码阅读方法与实现》阅读笔记一
查看>>
解决 sublime text3 运行python文件无法input的问题
查看>>
javascript面相对象编程,封装与继承
查看>>
Atlas命名空间Sys.Data下控件介绍——DataColumn,DataRow和DataTable
查看>>
Java中正则表达式的使用
查看>>
算法之搜索篇
查看>>
新的开始
查看>>
java Facade模式
查看>>
NYOJ 120校园网络(有向图的强连通分量)(Kosaraju算法)
查看>>
SpringAop与AspectJ
查看>>
Leetcode 226: Invert Binary Tree
查看>>
http站点转https站点教程
查看>>
解决miner.start() 返回null
查看>>
关于MFC中窗口的销毁
查看>>
bzoj 2007: [Noi2010]海拔【最小割+dijskstra】
查看>>
BZOJ 1001--[BeiJing2006]狼抓兔子(最短路&对偶图)
查看>>
C# Dynamic通用反序列化Json类型并遍历属性比较
查看>>