NIO笔记---上

时间:2024-01-23 13:08:53

小弟前端时间由于开发个管理系统导致断更了近20天!!马上就要春招了,学习了一下NIO,将笔记记录下,希望和我一样的18届毕业生都能找到满意的公司!!

 

本文记录了NIO与IO的区别,缓冲区的数据存取,直接缓冲区与非直接缓冲区,通道的原理与获取,通道之间的数据传输

.简介

1.NIO简介:  与原来的IO有同样的作用与目的,但是使用的方式完全不同,NIO支持面向缓冲区的,基于通道的IO操作.

2.NIOIO主要区别:

IO:

(1)面向流 (单向的,一个 输入,一个输出,InputStream,outputStream)

(2)阻塞IO

Nio

面向缓冲区

非阻塞IO   (Non Blocking IO)

选择器Selectors

 //阻塞和非阻塞,针对网络编程(网络IO)而言

3.NIO的核心在于:通道(Channel)和缓冲区(Buffer)

(1)通道(铁路)主要是用来连接的。缓冲区(火车 )负责存取数据,双向

(2)通道表示打开到IO设备(例如文件,套接字的连接)。若需要使用NIO系统,需要获取用于连接IO设备的通道以及用于容纳数据的缓冲区。然后操作缓冲区,对数据进行处理。

 

   通道负责连接,Buffer负责存取

二.缓冲区的数据存取

缓冲区(Buffer):在 Java NIO 中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据,根据数据类型不同(boolean 除外),提供了相应类型的缓冲区:
 ByteBuffer
 CharBuffer
 ShortBuffer
 IntBuffer
 LongBuffer
 FloatBuffer
 DoubleBuffer
 1.上述缓冲区的管理方式几乎一致,通过 allocate() 获取缓冲区

 

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

   2.缓冲区存取数据的两个核心方法:(执行存取之前先学4个属性)
    put() : 存入数据到缓冲区中
    get() : 获取缓冲区中的数据

//利用 put() 存入数据到缓冲区中
String str="asdfasdf";		
buf.put(str.getBytes());

 

3.缓冲区中的四个核心属性:
 capacity : 容量,表示缓冲区中最大存储数据的容量。一旦声明不能改变。
 limit : 界限,表示缓冲区中可以操作数据的大小。(limit 后数据不能进行读写)
 position : 位置,表示缓冲区中正在操作数据的位置。
 mark : 标记,表示记录当前 position 的位置。可以通过 reset() 恢复到 mark 的位置
 
 0 <= mark <= position <= limit <= capacity

4.

//切换读取数据模式
		buf.flip();

 

 5.

//利用 get() 读取缓冲区中的数据
		byte[] dst = new byte[buf.limit()];
		buf.get(dst);
		System.out.println(new String(dst, 0, dst.length));

 6.

 //rewind() : 可重复读
		buf.rewind();

 7.

 //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());

8.

if(buf.hasRemaining()){//判断缓冲区中是否还有剩余的数据

Buf.remaining();//获取缓冲区中可以操作的数量
}

三.直接缓冲区与直接缓冲区

非直接缓冲区:通过 allocate() 方法分配缓冲区,将缓冲区建立在 JVM 的内存中
直接缓冲区:通过 allocateDirect() 方法分配直接缓冲区,将缓冲区建立在物理内存中。

             优点:可以提高效率(物理内存映射文件)

             缺点:缓冲区进行分配和取消分配所需成本高,不易控制

                 //分配直接缓冲区
		ByteBuffer buf = ByteBuffer.allocateDirect(1024);
		//通过isDirect()判断是不是直接缓冲区
		System.out.println(buf.isDirect());

 四.通道的原理与获取

通道:用于源节点与目标节点的连接。在java nio中负责缓冲区中数据的传输。Chanel本身不存储数据,因此需要配合缓冲区进行传输。

1.通道的主要实现类

Java.nio.channels.Channel接口

              FileChannel

              SocketChannel(tcp)

              ServerSocketChannel(tcp)

             DatagramChannel(udp)

          2.获取通道

(1)java 针对支持通道的类提供了getChannel()方法

       本地IO

         FileInputStream/FileOutputStream

         RandomAccessFile随机存取文件流

   网络io

         Socket

          Serversocket

          Datagramsocket

FileInputStream fis = new FileInputStream("d:/1.txt");
FileChannel inChannel== fis.getChannel();

 (2)通道之间的数据传输

transferFrom()

transferTo()这两方法用其中一个就行

                FileChannel inChannel = FileChannel.open(Paths.get("d:/1.txt"), StandardOpenOption.READ);
		FileChannel outChannel = FileChannel.open(Paths.get("d:/2.txt"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
		
//		inChannel.transferTo(0, inChannel.size(), outChannel);
		outChannel.transferFrom(inChannel, 0, inChannel.size());
		
		inChannel.close();
		outChannel.close();

 END!

小弟下次会记录一下分散读取与聚集写入,字符集,阻塞与非阻塞相关的。希望可以帮到想要学习的人。因为小弟也没在真正项目中用过NIO,如果哪写的不对,希望指正。