A brief introduction to JavaINO (1)

Javaino

  • That is Java New IOalso called non-blocking IONone Blocking IO
  • Is a brand new and JDK 1.4later providedIO API

2. Function

  • Provides a IOdifferent IOworking method from the standard
  • Alternative to the standard Java IOofIO API

3. New features

In contrast Java IO, NIOthe new features are as follows

Insert picture description here

The main difference between Java NIO and IO

IO style NIO style
Byte-oriented Cache-oriented
Blocking IO Non-blocking (Non Blocking IO)
(no) Selectors

4. Core components

Java NIOThe core components include:

  • Channel ( Channel)
  • Buffer ( Buffer)
  • Selector ( Selectors)

5. NIO_Buffer_ allocation and access

  • Three important parameters in the cache
/**
    * 测试缓存分配
    */
   @Test

   public void test1(){
       // capacity 分配缓存大小
       int capacity = 1024;
       ByteBuffer buffer = ByteBuffer.allocate(capacity);

       System.out.println("capacity(缓存大小):" + buffer.capacity());
       System.out.println("limit(限制):" + buffer.limit());
       System.out.println("position(起始位置):" + buffer.position());

       System.out.println("--------------------------------------------------------");
       // 向缓存中存数据 put();
       buffer.put("hello world!".getBytes());

       System.out.println("capacity(缓存大小):" + buffer.capacity());
       System.out.println("limit(限制):" + buffer.limit());
       System.out.println("position(起始位置):" + buffer.position());

       System.out.println("--------------------------------------------------------");

       //flip() 方法切换到读的状态
       buffer.flip();

       System.out.println("capacity(缓存大小):" + buffer.capacity());
       System.out.println("limit(限制):" + buffer.limit());
       System.out.println("position(起始位置):" + buffer.position());
       System.out.println("--------------------------------------------------------");

       // 从缓存中取数据 get()
       //byte b = buffer.get();
       byte[] dst = new byte[buffer.limit()];
       buffer.get(dst);
       System.out.println(new String(dst));

       System.out.println("capacity(缓存大小):" + buffer.capacity());
       System.out.println("limit(限制):" + buffer.limit());
       System.out.println("position(起始位置):" + buffer.position());
       System.out.println("--------------------------------------------------------");

       // rewind() 重写 其起始位置从零开始
       buffer.rewind();
       System.out.println("capacity(缓存大小):" + buffer.capacity());
       System.out.println("limit(限制):" + buffer.limit());
       System.out.println("position(起始位置):" + buffer.position());
       System.out.println("--------------------------------------------------------");

       //clear() 清空缓存 限制增大 limit = capacity
       buffer.clear();
       System.out.println("capacity(缓存大小):" + buffer.capacity());
       System.out.println("limit(限制):" + buffer.limit());
       System.out.println("position(起始位置):" + buffer.position());
       System.out.println((char) buffer.get());
       System.out.println("--------------------------------------------------------");

   }

6. Mark parameter and other methods of NIO_Buffer_ cache

/**
     * 测试标记
     */

    @Test

    public void test2() {
        // capacity 分配缓存大小
        int capacity = 1024;
        ByteBuffer byteBuffer = ByteBuffer.allocate(capacity);

        byteBuffer.put("Hello world!".getBytes());
        //flip() 方法切换到读的状态
        byteBuffer.flip();

        byte[] b = new byte[2];
        byteBuffer.get(b);
        System.out.println(new String(b));
        System.out.println("--------------------------------------------------------");


        System.out.println("capacity(缓存大小):" + byteBuffer.capacity());
        System.out.println("limit(限制):" + byteBuffer.limit());
        System.out.println("position(起始位置):" + byteBuffer.position());
        // mark()做标记
        byteBuffer.mark();
        byteBuffer.get(b);

        System.out.println(new String(b));
        System.out.println("--------------------------------------------------------");


        System.out.println("capacity(缓存大小):" + byteBuffer.capacity());
        System.out.println("limit(限制):" + byteBuffer.limit());
        System.out.println("position(起始位置):" + byteBuffer.position());
        // reset()回到mark标记的位置  Invariants: mark <= position <= limit <= capacity
        byteBuffer.reset();

        System.out.println("--------------------------------------------------------");

        System.out.println("capacity(缓存大小):" + byteBuffer.capacity());
        System.out.println("limit(限制):" + byteBuffer.limit());
        System.out.println("position(起始位置):" + byteBuffer.position());


    }
    

7. NIO_Buffer_ direct cache and indirect cache

/**
  * 直接缓存区
  */
 @Test
 public void test3(){
     // 分配直接缓存区

     ByteBuffer buf = ByteBuffer.allocateDirect(1024);
     System.out.println("capacity(缓存大小):" + buf.capacity());
     System.out.println("limit(限制):" + buf.limit());
     System.out.println("position(起始位置):" + buf.position());

     System.out.println("是否为直接缓存区:" + buf.isDirect());
 }

8. Type and copying method of NIO_Buffer_ channel


 @Test
    /**
     * 利用通道channel进行文件复制
     */
    public void test4(){
        FileInputStream fin = null;
        FileOutputStream fout = null;

        FileChannel finChannel = null;
        FileChannel foutChannel = null;

        try {
            fin = new FileInputStream("3.jpg");
            fout = new FileOutputStream("4.jpg");
            // 获得通道
            finChannel = fin.getChannel();
            foutChannel = fout.getChannel();
            // 获得缓存
            ByteBuffer buffer = ByteBuffer.allocate(1024);//反复读3.jpg的字节到缓存 如果=1 即为读完

            while(finChannel.read(buffer)!=-1){
                //position定位到开头以便从缓存中获取数据
                buffer.flip();
                // 将缓存数据写入通道
                foutChannel.write(buffer);
                //清空缓存position定位到开头以便下次读通道读字节
                buffer.clear();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
             // 关闭通道
            try {
                if(finChannel!=null) finChannel.close();
                if(foutChannel!=null) foutChannel.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    @Test
    /**
     * JDK1.7之后获得的通道的方法
     */
    public void test5(){

        FileChannel fin = null;
        FileChannel fout = null;

        try {
            fin = FileChannel.open(Paths.get("3.jpg"), StandardOpenOption.READ);
            fout = FileChannel.open(Paths.get("5.jpg"),StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE_NEW);

            // 创建缓存
            MappedByteBuffer finmap = fin.map(FileChannel.MapMode.READ_ONLY,0,fin.size());
            MappedByteBuffer outmap = fout.map(FileChannel.MapMode.READ_WRITE,0,fin.size());
            //获得3.jpg字节

            byte[] dst = new byte[finmap.limit()];
            finmap.get(dst);
            // 把字节放入缓存
            outmap.put(dst);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(fin != null) fin.close();
                if(fout != null) fin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * JDK1.7之后的获取通道方法
     * 通道间直接缓存交换数据
     * transferFrom()
     * transferTo()
     */
    @Test
    public void test6(){


        FileChannel fin = null;
        FileChannel fout = null;

        try {
            fin = FileChannel.open(Paths.get("3.jpg"), StandardOpenOption.READ);
            fout = FileChannel.open(Paths.get("6.jpg"),StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE_NEW);

            // 创建缓存
           fin.transferTo(0,fin.size(),fout);
           fout.transferFrom(fin,0,fin.size());


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(fin != null) fin.close();
                if(fout != null) fin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

9. Dispersion and aggregation of INO_Buffer

/**
     * 分散和聚集
     */
    @Test
    public void test7() throws Exception {

        // 获得通道

        FileChannel channel = new RandomAccessFile("src/edu/xalead/TestBuffer.java",
                                                   "rw").getChannel();
        // 创建缓存
        ByteBuffer buffer1 = ByteBuffer.allocate(1024);
        ByteBuffer buffer2 = ByteBuffer.allocate(1024);
        ByteBuffer buffer3 = ByteBuffer.allocate(1024);
        ByteBuffer buffer4 = ByteBuffer.allocate(1024);
        ByteBuffer buffer5 = ByteBuffer.allocate(1024);
        ByteBuffer buffer6 = ByteBuffer.allocate(1024);
        ByteBuffer buffer7 = ByteBuffer.allocate(1024);
        ByteBuffer buffer8 = ByteBuffer.allocate(1024);
        ByteBuffer buffer9 = ByteBuffer.allocate(1024);
        ByteBuffer buffer10 = ByteBuffer.allocate(1024);

        // 分散读取
        ByteBuffer[] buffers = {buffer1,buffer2,buffer3,buffer4, buffer5, buffer6, buffer7, buffer8,buffer9,buffer10};

        channel.read(buffers);

        for(ByteBuffer buffer: buffers){

            System.out.println(new String(buffer.array(),0,buffer.limit()));
            System.out.println("-----------------------------------------------------------");
        }
        //聚集写入
        FileChannel channel1 = new RandomAccessFile("T.java","rw").getChannel();
        // 把buffer的position恢复到起始位置

        for(ByteBuffer buffer:buffers){
            buffer.flip();
        }
        channel1.write(buffers);
        channel.close();
        channel1.close();

    }
  

10 NIO summary

Buffer

Cache type (used to cache different types of data, omitting type conversion)

  • ByteBuffer
  • IntBuffer
  • ShortBuffer
  • LongBuffer
  • CharBuffer
  • FloatBuffer
  • DoubleBuffer

Two core methods of caching and accessing data

  • put () save data to cache
  • get () fetch data from cache

Four parameters in the cache

  • capacity
  • limit
  • position
  • mark

Direct buffer and indirect buffer:

Non-direct buffer: allocate the buffer by the allocate () method and establish the buffer in the JVM's memory
Direct buffer: allocate the direct buffer by the allocateDirect () method and establish the buffer in the physical memory. Can improve efficiency

  1. The byte buffer is either direct or indirect. If it is a direct byte buffer, the Java Virtual Machine will do its best to perform native I / O operations directly on this buffer. That is to say, before each (or after) a native I / O operation of the underlying operating system is called, the virtual machine will try to avoid copying the contents of the buffer into the intermediate buffer (or copying the content from the intermediate buffer ).
  2. Direct byte buffers can be created by calling this class's allocateDirect () factory method. The buffers returned by this method usually cost more to allocate and deallocate than non-direct buffers. The contents of direct buffers can reside outside of the conventional garbage collection heap, so their impact on the memory requirements of the application may not be obvious. Therefore, it is recommended that direct buffers be mainly allocated to large, persistent buffers that are susceptible to the underlying system's native I / O operations. In general, it is best to allocate direct buffers only when they can provide a significant benefit in program performance.
  3. Direct byte buffers can also be created by directly mapping the file area into memory through the FileChannel map () method. This method returns MappedByteBuffer . The implementation of the Java platform facilitates the creation of direct byte buffers from native code through JNI. If a buffer instance in these buffers refers to an inaccessible memory area, attempting to access the area will not change the contents of the buffer, and will cause a throw during the access or at a later time Uncertain exceptions.
  4. Whether the byte buffer is a direct buffer or an indirect buffer can be determined by calling its isDirect () method. This method is provided to enable explicit buffer management in performance-critical code.
101 original articles published · Liked 47 · Visitors 10,000+

Guess you like

Origin blog.csdn.net/TONGZONGE/article/details/104453138