Java 网络编程【1】
1.缓冲区概念
- Java进程执行 I/O 操作时,是向操作系统发出请求,从操作系统(缓冲区)那里读取数据,而操作系统要从其他地方读取数据(磁盘或者网络),先把数据整体的存到一个地方,这个地方成为缓冲区,缓冲区有内核空间缓冲区和用户空间缓冲区。
- 如Java进程使用read()方法读取文件内容时(如test.txt),jvm向操作系统发出请求,操作系统内核随即向磁盘控制硬件发出命令,要求其从磁盘读取数据。磁盘控制器把数据直接写入内核内存缓冲区,一旦磁盘控制器把缓冲区装满,内核即把数据从内核空间的临时缓冲区拷贝到jvm进程执行 read( )调用时指定的缓冲区,read()就可以获得文件内容了。
- 读操作就是:内核空间读取数据到缓冲区->拷贝数据到用户空间缓冲区。
- 写操作就是:用户空间缓冲区向内核空间缓冲区填数据->内核向其他地方写数据
2.Java NIO
- 早期JVM 在解释字节码时(即运行时)优化的很少,运行效率较低,受cpu的束缚较大,内核I/O的束缚较小,Java进程的io基本能和内核io匹配。而今,jvm解释字节码的优化加上硬件设备性能的提升,代码编译速度很快,多数 Java 应用程序已不再受 CPU 的束缚(把大量时间用在执行代码上),而更多时候是受 I/O 的束缚。
- jdk1.4以前,JVM 自身在 I/O 方面效率欠佳。操作系统与 Java 基于流的 I/O模型有些不匹配(操作系统io快于Java io),操作系统送来整缓冲区的数据,而Java.io却要单个字节、几行文本(小块数据)的进行读写,操作系统喜欢整卡车地运来数据,java.io 类则喜欢一铲子一铲子地加工数据。速度当然跟不上,进程阻塞在这里,cpu利用率不够。
- jdk1.4以后,有了NIO,就可以轻松地把一卡车数据备份到您能直接使用的地方(Buffer 对象),一个Buffer对象是固定数量的数据容器。其作用是一个存储器,或者分段运输区,数据可被存储在这里,并在之后用于检索。
3.Java.nio的Buffer缓冲区
- Buffer 类似于一个数组,相比一个简单数组的优点是,它将关于数据的数据内容和信息包含在一个单一的对象中。
- Buffer缓冲区属性:
- 容量(Capacity):缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,并且永远不能被改变。
- 上界(Limit):缓冲区的第一个不能被读或写的元素。或者说,缓冲区中现存元素的计数。
- 位置(Position):下一个要被读或写的元素的索引。位置会自动由相应的 get( )和 put( )函数更新。
- 标记(Mark):一个备忘位置。调用 mark( )来设定 mark = postion。调用 reset( )设定 position =mark。标记在设定前是未定义的( undefined) 。
- 这四个属性之间总是遵循以下关系:
0 <= mark <= position <= limit <= capacity