Java IO学习总结(四)

1、NIO缓存

      NIO采用内存映射文件的方式来处理输入输出流,将文件或者文件的一段区域映射到内存中,这样就能够像访问内存同样访问文件,处理速度比传统的输入输出流要快。最主要的两个核心对象是Channel(通道)和Buffer(缓冲)。app

1)Buffer大数据

     Buffer是一个抽象类,最主要的实现类是ByteBuffer,其余基本数据类型都有对应的buffer类。经常使用ByteBuffer和CharBuffer;spa

     建立一个Buffer对象,经过static XXBuffer allocate(int capacity)方法,capacity表明容量。code

     Buffer中主要有三个重要的概念,容量(capacity)、界限(limit)和位置(position)对象

     容量:表示缓冲区的最大数据容量,不能够为负值,建立后不能够改变。blog

     界限:表示数据不能够被读出或者写入的缓冲区索引位置。索引

     位置:表示下一个能够被读出或者写入的缓冲区位置索引,当建立一个buffer对象以后,position为0,从中读取两条数据以后,position则为2,指向buffer中的第三个数据位置。写入时相似,position自动向后移动位置。ip

     Buffer中两个重要方法:flip()和clear();执行flip()方法以后,limit移动到position位置,position置为0,为输出数据作好准备,;执行clear()方法以后,limit移动到capacity位置,position位置置为0,为写入数据作好准备。内存

Buffer经常使用操做示例代码:

public class BufferTest {
    public static void main(String[] args) {
        // 建立Buffer
        CharBuffer buff = CharBuffer.allocate(10);
        
        // 初始化时:position位置为0,limit位置等于capacity
        System.out.println("缓冲区容量:" + buff.capacity());
        System.out.println("初始化position位置:" + buff.position());
        System.out.println("初始化limit位置:" + buff.limit());
        
        // 向缓冲区中放入三条数据
        buff.put('A');
        buff.put('B');
        buff.put('C');
        // 此时position位置为3,limit位置等于capacity
        System.out.println("装载数据时position位置:" + buff.position());
        System.out.println("装载数据时limit位置:" + buff.limit());
        
        // 装载数据结束
        buff.flip();
        // 查看此时position位置为0,limit位置为3
        System.out.println("装载数据完成position位置:" + buff.position());
        System.out.println("装载数据完成limit位置:" + buff.limit());
        
        // 取出数据,只有使用buff.get()方法时,position自动向后移动位置,使用buff.get(X)position位置不变。
        System.out.println("取出第一个数据" + buff.get());
        System.out.println("取出数据position位置:" + buff.position());
        
        // 取出数据完成
        buff.clear();
        // 查看此时position位置为0,limit位置等于capacity
        System.out.println("取出数据完成position位置:" + buff.position());
        System.out.println("取出数据完成limit位置:" + buff.limit());
    }
}

2)Channel

     Channel相似于传统的流对象,能够直接将指定文件的部分或者所有映射成Buffer,程序不能直接访问Channel,必须经过Buffer交互;全部的Channel都不能经过构造器来直接建立,而是经过传统的节点InputStream、OutStream的getChannel()的方法返回对于的Channel。

     Channel有三个主要的方法,map()、read()和write(),map()方法用于将Channel中数据映射成ByteBuffer.

示例代码

public class ChannelTest {
    public static void main(String[] args) {
        try {
            // 建立文件
            File file = new File("d:\\test.txt");
            
            // 建立输入和输出Channel
            FileChannel fic = new FileInputStream(file).getChannel();    
            FileChannel foc = new FileOutputStream("d:\\channel.txt").getChannel();
            
            // 将文件内容所有映射为ByteBuffer
            MappedByteBuffer buffer = fic.map(MapMode.READ_ONLY, 0, file.length());
            // 将buffer中数据之间输出到FileChannel中
            foc.write(buffer);
            // 初始化缓冲区
            buffer.clear();
            
            // 建立解码器用于buffer转换
            Charset charset = Charset.forName("GBK");
            CharsetDecoder cd = charset.newDecoder();
            
            // 将byteBuffer转换为charBuffer用于数据输出展现
            CharBuffer charbuff = cd.decode(buffer);
            System.out.println("数据为:" + charbuff);
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

另一种读取方式

public class ChannelTest1 {
    public static void main(String[] args) {
        try {
            File file = new File("d:\\test.txt");
            FileChannel fci = new FileInputStream(file).getChannel();
            
            // 定义buffer
            ByteBuffer buff = ByteBuffer.allocate(256);
            
            while(fci.read(buff) != -1){
                // 锁定缓存区域,防止读取null
                buff.flip();
                // 建立解码器转换为charbuffer输出
                Charset charset = Charset.forName("GBK");
                CharsetDecoder decode = charset.newDecoder();
                System.out.println(decode.decode(buff));
                
                // 数据读取完以后,初始化缓冲区
                buff.clear();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
相关文章
相关标签/搜索