NIO基本概念

1.  IO和NIO的区别
 IO     面向流(stream oriented)  阻塞(blocking io) 无  
                NIO  面向缓冲区(buffer oriented)非阻塞(Non blocking io)选择器(selectors)
Java NIO的系统核心在于:通道(Channel)和缓冲区(Buffer)。通道表示打开到IO设备(例如文件、套接字)的连接。若需要使用NIO
系统,需要获取用于连接IO设备的通道和用于容纳数据的缓冲区。然后操作缓冲区,对数据进行处理。
简言之:Channel负责传输,Buffer负责存储
2.缓冲区的数据存取
 底层数据  根据数据类型的不同(boolean) 提供对应类型的缓冲区
 ByteBuffer
 CharBuffer
 ShortBuffer
 IntBuffer
 LongBuffer
 FloatBuffer
 DoubleBuffer
 
 ByteBuffer buf = new ByteBuffer,allocate(1024);
 缓冲区的核心方法:put()存数据     get()取出数据
 缓冲区的四个核心属性:capacity容量    limit界限   position位置  mark标记(reset()方法恢复position的位置)
 0 <=mark<=position<=limit<=capacity
 flip()切换到读取数据的模式 
 rewind()可重复读数据
 clear()清空缓冲区 数据依然存在,但是处于“被遗忘”状态
3.直接缓冲区和非直接缓冲区
 直接缓冲区:通过allocate()分配,将缓冲区建立在JVm内存中
 非直接缓冲区:通过allocateDirect()分配,将缓冲区建立在物理内存中,可以提高效率
 isDirect()判断是否是直接缓冲区
 
4非直接缓冲区进行文件复制
package com.hpd.nio;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import org.junit.jupiter.api.Test;

public class TestChannel {
    //非直接缓冲区进行文件复制
    @Test
    public void test1() {
        FileInputStream fin = null;
        FileOutputStream fos = null;
        // 获取通道
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
            fin = new FileInputStream("1.png");
            fos = new FileOutputStream("2.png");

            inChannel = fin.getChannel();
            outChannel = fos.getChannel();

            // 分配指定大小的缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(1024);

            // 将通道中的数据写入缓冲区
            while ((inChannel.read(buffer)) != -1) {
                buffer.flip(); // 切换成读模式
                // 将缓冲区中的数据写入通道
                outChannel.write(buffer);
                buffer.clear(); // 清空缓冲区
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } 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 (fin != null) {
                try {
                    fin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }

}

5.直接缓冲区进行文件复制

//直接缓冲区进行文件的复制(内存映射文件)
    @Test
    public void test2() throws IOException {
        FileChannel inChannel = FileChannel.open(Paths.get("1.png"), StandardOpenOption.READ);
        FileChannel outChannel = FileChannel.open(Paths.get("3.png"),StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE);
        
        //内存映射文件
        MappedByteBuffer inMapBuffer = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
        MappedByteBuffer outMapBuffer = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
        
        //直接对缓冲区进行数据的读写操作
        byte[] dst  = new byte[inMapBuffer.limit()];
        inMapBuffer.get(dst);
        outMapBuffer.put(dst);
        
        inChannel.close();
        outChannel.close();    
    }
    

 

 

 
 
posted @ 2019-01-10 09:01  Tamako521  阅读(392)  评论(0编辑  收藏  举报