Java之NIO

想要学习Java的Socket通信,首先要学习Java的IO和NIO基础,这方面可以阅读《Java NIO 系列教程》。

下面展示自己代码熟悉Java的NIO编程的笔记。

1、缓冲区(Buffer)

/*
 * 一、缓冲区(Buffer):在Java 中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据
 *       
 *       根据数据类型不同(boolean除外),提供了相应类型的缓冲区
 *         ByteBuffer 那么实际上最常用的,因为网络传输的字节就是Byte
 *      CharBuffer
 *       ShortBuffer
 *        IntBuffer
 *         LongBuffer
 *      FloatBuffer
 *      DoubleBuffer
 *     
 *    上述缓冲区的管理方式几乎一致,通过allocate()获取缓冲区
 *    
 *  二、缓冲区存储数据的两个核心方法
 *      put()  : 存入数据到缓冲区中
 *      get()  : 获取缓冲区中的数据
 *      
 *  三、缓冲区中的四个核心属性
 *      capacity : 容量,表示缓冲区中最大存储数据的容量
 *      limit    : 界限,标识缓冲区中可以操作数据的大小(limit后面的数据不能进行读写的)
 *      position : 位置,标识缓冲区中正在操作数据的位置
 *      
 *      mark     : 标记,标识记录当前position的位置,可以通过reset()恢复到mark的位置
 *  
 *      0 <= mark <= position <= limit <= capacity
 *  四、直接缓冲区和非直接缓冲区
 *      非直接缓冲区: 通过allocate()方法分配缓冲区,将缓冲区建立在JVM的内存中。
 *      直接缓冲区 :  通过allockateDirect()方法分配直接缓存区,将缓冲区建立在物理内存中。可以提高效率。
 *                  如果有数据需要一直在内存空间中重复用,并且数据量不大的情况下,就用allockateDirect()这种方法。
 *                  毕竟内存空间是有限的。
 */

相关代码:

  1 package com.demo.test;
  2
  3 import java.nio.ByteBuffer;
  4
  5 public class TestBuffer {
  6
  7     public void test3(){
  8         // 分配直接缓冲区
  9         ByteBuffer buf = ByteBuffer.allocate(1024);
 10         System.out.println(buf.isDirect());// 判断这个缓冲区是直接还是非直接的。
 11     }
 12
 13     public void test2(){
 14         String str = "abcde";
 15
 16         // 1、分配一个指定大小的缓冲区
 17         ByteBuffer buf = ByteBuffer.allocate(1024);
 18
 19         // 2、利用put()存入数据到缓冲区中
 20         System.out.println("往buf插入所有字符串的bytes是:"+str.getBytes());
 21         buf.put(str.getBytes());
 22
 23         buf.flip();// 将插入模式转为查询模式,就是查询position位置会回到0
 24
 25         System.out.println("创建和缓冲区等长度的字节数组,用来从缓冲区取出字节并存储以待读取操作");
 26         byte[] dst  = new byte[buf.limit()];
 27         System.out.println("从缓冲区中去除0开始的2位字节数据放进数组dst中");
 28         buf.get(dst, 0, 2);
 29         System.out.println("打印dst字节数组"+new String(dst, 0, 2));
 30         System.out.println("现在缓冲区的操作起始位置:"+buf.position());
 31
 32         // mark(); 标记
 33         System.out.println("标记");
 34         buf.mark();
 35         buf.get(dst, 2, 2);// 取出从2开始的2位字节数据放进
 36         System.out.println("打印dst字节数组"+new String(dst, 2, 2));
 37         System.out.println("现在缓冲区的操作起始位置:"+buf.position());
 38
 39         // reset(); 回复到mark的位置
 40         buf.reset();
 41         System.out.println("reset重置之后,缓冲区的操作起始位置回到:"+buf.position());
 42
 43         // 判断缓冲区中是否还有剩余的数据
 44         if(buf.hasRemaining()){
 45             // 获取缓冲区还可以操作的数量
 46             System.out.println("缓冲区还有可以操作的数量"+buf.remaining());
 47         }
 48     }
 49
 50     public void test(){
 51         String str = "abcde";
 52
 53         // 1、分配一个指定大小的缓冲区
 54         ByteBuffer buf = ByteBuffer.allocate(1024);
 55         System.out.println("--调用allocate之后--");
 56         System.out.println(buf.capacity());
 57         System.out.println(buf.limit());
 58         System.out.println("position:"+buf.position());
 59
 60         // 2、利用put()存入数据到缓冲区中
 61         System.out.println("字符串的bytes是:"+str.getBytes());
 62         buf.put(str.getBytes());
 63
 64         System.out.println("--调用put之后--");
 65         System.out.println(buf.capacity());
 66         System.out.println(buf.limit());
 67         System.out.println("position:"+buf.position());
 68
 69         // 3、前面是存入数据的模式,存入5个字节之后,position的位置从原本0现在到5了
 70         buf.flip();
 71         //   现在要将存储数据模式改成读取模式,position的位置会变回为0
 72
 73         System.out.println("--调用flip切换模式之后--");
 74         System.out.println(buf.capacity());
 75         System.out.println(buf.limit());
 76         System.out.println("position:"+buf.position());
 77
 78         // 4、利用get()读取缓冲区中的数据
 79         byte[] dst = new byte[buf.limit()];// 创建和缓冲区一样大的字节数据
 80         buf.get(dst);
 81         System.out.println(new String(dst,0,dst.length));
 82
 83         System.out.println("--调用get()切换模式之后--");
 84         System.out.println(buf.capacity());
 85         System.out.println(buf.limit());
 86         System.out.println("position:"+buf.position());// 打印输出的结果会发现position变回5了
 87
 88         // 5、可重复读取
 89         buf.rewind();
 90
 91         System.out.println("--调用rewind()切换模式之后--");
 92         System.out.println(buf.capacity());
 93         System.out.println(buf.limit());
 94         System.out.println("position:"+buf.position());
 95
 96         // 6、清空缓冲区。但是缓冲区中的数据依然存在,但是出于“被遗忘”状态
 97         buf.clear();
 98
 99         System.out.println("--调用clear()切换模式之后--");
100         System.out.println(buf.capacity());
101         System.out.println(buf.limit());
102         System.out.println("position:"+buf.position());
103
104         // 看看缓冲区有没有数据
105         System.out.println((char)(buf.get()+1));
106
107     }
108 }

2、通道(Channel)

由java.nio.channels包定义的。Channel表示IO源与目标打开的连接。Channel类似于传统的“流”。只不过Channel本身不能直接访问数据,Channel只能与Buffer进行交互。

先完成文件的复制:

时间: 2024-07-30 13:52:26

Java之NIO的相关文章

java的nio之:java的nio系列教程之channel的概念

一:java的nio的channel Java NIO的通道类似流,但又有些不同: ==>既可以从通道中读取数据,又可以写数据到通道.但流的读写通常是单向的. ==>通道可以异步地读写. ==>通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入. 正如上面所说,从通道读取数据到缓冲区,从缓冲区写入数据到通道.如下图所示: 二:java的nio的channel的实现 这些是Java NIO中最重要的通道的实现: ==>FileChannel  : ==>

java的nio之:java的nio系列教程之概述

一:java的nio的核心组件?Java NIO 由以下几个核心部分组成: ==>Channels ==>Buffers ==>Selectors 虽然Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Selector 构成了核心的API.其它组件,如Pipe和FileLock,只不过是与三个核心组件共同使用的工具类.因此,在概述中我将集中在这三个组件上.其它组 件会在单独的章节中讲到. Channel 和 Buffer 基本上,所有的 IO 在

java的nio包的SelectionKey,Selector,SelectableChannel三者的缠绵关系概述

猛击这里 java的nio包的SelectionKey,Selector,SelectableChannel三者的缠绵关系概述

java使用NIO构造http请求

使用java的NIO来构造http请求体,并且取得响应内容. package com.test.nio; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; public class TestSocketForBaidu { /** * @param args * @throws

不惑JAVA之JAVA基础 - NIO (一)

JAVA中最可以大书特书的我觉得至少有两个:一个是NIO,另外一个就是JVM了.这也就是为什么一直我没有去写这两个知识点的原因,因为我一直找不出来一个可以在一篇博文中全部覆盖这个知识点的总结. 这两天翻了一下了JAVA中的圣经<think in java>和<Java核心技术>,虽然写的很好,但感觉写的也不是太符合我想一篇博文覆盖NIO知识点的要求.由于NIO本来就是技术难点,并且java对IO的设计和使用也较为复杂难懂.我也是能力有限如有说明不到位或错误的地方请大家指出. 本文参

Tinking in Java ---Java的NIO和对象序列化

前面一篇博客的IO被称为经典IO,因为他们大多数都是从Java1.0开始就有了的:然后今天这篇博客是关于NIO的,所以的NIO其实就是JDK从1.4开始,Java提供的一系列改进的输入/输出处理的新功能,这些新功能被统称为新IO(New IO ,简称NIO).另一个概念对象序列化指的是将那些实现了Serializable接口的对象转换成一个字节序列,并能够在以后将这个字节序列再转换成原来的对象.这样的话我们就可以将对象写入磁盘中,或者是将对象在网络上进行传递.下面就对这两个内容进行总结. 一.J

JAVA bio nio aio

[转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步非阻塞? 7 什么是异步阻塞? 8 什么是异步非阻塞? 散仙不才,在查了一部分资料后,愿试着以通俗易懂的方式解释下这几个名词.如有不足之处,还望告知. 在弄清楚上面的几个问题之前,我们首先得明白什么是同步,

输入和输出--java的NIO

Java的NIO 实际开发中NIO使用到的并不多,我并不是说NIO使用情景不多,是说我自己接触的并不是很多,前面我在博客园和CSDN上转载了2篇别人写的文章,这里来大致总结下Java的NIO,大概了解下. NIO和传统IO的对比: 在使用传统IO的时候,不管是使用节点流这种底层流还是使用处理流这种高级流,在底层操作的都是字节,所以性能就不会很好,在使用BufferedReader这种高级流的时候还会阻塞该线程,所以Java1.4后出现了NIO. NIO相关的类都放在了Java.nio包下,他的功

java之NIO编程

所谓行文如编程,随笔好比java文件,文章好比类,参考文献是import,那么目录就是方法定义. 本篇文章处在分析thrift的nonblocking server之前,因为后者要依赖该篇文章的知识.若两文同一篇,那即是两类共享同一文件,其中有一个必为public,若一文在另一文中,即为内部类.按编程规范,还是分成两篇来写为好. java之NIO详解系列文章,比较好的,还是推荐这篇http://tutorials.jenkov.com/java-nio/overview.html.本文只是简略总