操做系统要移动的是大块数据(缓冲区), 这每每是在硬件直接存储器存取 (DMA) 的协助下完成的.数组
例如硬盘操做, 磁盘控制器经过 DMA 直接将数据写入内核的内存缓冲区. 一旦磁盘控制器完成了缓存的填写, 内核从内核空间的临时缓存拷贝数据到用户控件缓存中.缓存
因此操做系统是以卡车的形式拷贝数据, 可是 Java 基于流的 I/O 模型, 是一铲子一铲子的加工数据.socket
面向流I/O的系统: 一次处理一个字节的数据. 一个输入流每次会读入一个字节的数据,一个输出流一样每次次消费一个字节的数据. 例如 Java 中的 SocketInputStream
和 FileInputStream
都是一次读取一个.操作系统
虽然你读取的数据时, 可能会使用以下代码:code
byte[] receiveBuffer = new byte[128]; String clientMessage = ""; if((receiveBytes=in.read(receiveBuffer))!=-1) {
这里虽然指定了读取数据的大小, 可是要注意, 在读取时, 并非一次性所有读取完成, 而是一个一个进行读取, 读取的次数就是数组的大小.内存
面向块I/O的系统: 以块为单位处理数据. 每一个操做步骤会生成或消费一个块的数据.cli
先建立一个缓冲区硬件
// 缓冲区的大小 private final static int BUFFER_SIZE = 1024; // 缓冲区 private ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
而后使用相似如下代码来读取数据到缓冲区.数据
int len = 0; while ((len = socketChannel.read(buffer)) > 0) {
也就是说, 直接读取缓冲区大小的一块数据, 保存到缓冲区中.static
值得注意的是: 虽然建立缓冲区, 和上面建立的
byte[]
数组做用是同样的, 都是用来存储数据. 可是千万不要搞混了, 流 IO 和 块 IO 的底层处理方式不同的.