当前位置: 首页 > news >正文

破解asp网站后台地址百度收录网站

破解asp网站后台地址,百度收录网站,网站SEO建设,wordpress frame主题转载自 Java NIO#xff1a;Buffer、Channel 和 Selector本文将介绍 Java NIO 中三大组件 Buffer、Channel、Selector 的使用。 本来要一起介绍非阻塞 IO 和 JDK7 的异步 IO 的#xff0c;不过因为之前的文章真的太长了#xff0c;有点影响读者阅读#xff0c;所以这里将它…转载自 Java NIOBuffer、Channel 和 Selector本文将介绍 Java NIO 中三大组件 Buffer、Channel、Selector 的使用。 本来要一起介绍非阻塞 IO 和 JDK7 的异步 IO 的不过因为之前的文章真的太长了有点影响读者阅读所以这里将它们放到另一篇文章中进行介绍。 Buffer 一个 Buffer 本质上是内存中的一块我们可以将数据写入这块内存之后从这块内存获取数据。 java.nio 定义了以下几个 Buffer 的实现这个图读者应该也在不少地方见过了吧。其实核心是最后的 ByteBuffer前面的一大串类只是包装了一下它而已我们使用最多的通常也是 ByteBuffer。 我们应该将 Buffer 理解为一个数组IntBuffer、CharBuffer、DoubleBuffer 等分别对应 int[]、char[]、double[] 等。 MappedByteBuffer 用于实现内存映射文件也不是本文关注的重点。 我觉得操作 Buffer 和操作数组、类集差不多只不过大部分时候我们都把它放到了 NIO 的场景里面来使用而已。下面介绍 Buffer 中的几个重要属性和几个重要方法。 position、limit、capacity 就像数组有数组容量每次访问元素要指定下标Buffer 中也有几个重要属性position、limit、capacity。最好理解的当然是 capacity它代表这个缓冲区的容量一旦设定就不可以更改。比如 capacity 为 1024 的 IntBuffer代表其一次可以存放 1024 个 int 类型的值。一旦 Buffer 的容量达到 capacity需要清空 Buffer才能重新写入值。 position 和 limit 是变化的我们分别看下读和写操作下它们是如何变化的。 position 的初始值是 0每往 Buffer 中写入一个值position 就自动加 1代表下一次的写入位置。读操作的时候也是类似的每读一个值position 就自动加 1。 从写操作模式到读操作模式切换的时候flipposition 都会归零这样就可以从头开始读写了。 Limit写操作模式下limit 代表的是最大能写入的数据这个时候 limit 等于 capacity。写结束后切换到读模式此时的 limit 等于 Buffer 中实际的数据大小因为 Buffer 不一定被写满了。初始化 Buffer 每个 Buffer 实现类都提供了一个静态方法 allocate(int capacity) 帮助我们快速实例化一个 Buffer。如 1234ByteBuffer byteBuf ByteBuffer.allocate(1024);IntBuffer intBuf IntBuffer.allocate(1024);LongBuffer longBuf LongBuffer.allocate(1024);// ...另外我们经常使用 wrap 方法来初始化一个 Buffer。 123publicstatic ByteBuffer wrap(byte[] array) {    ...}填充 Buffer 各个 Buffer 类都提供了一些 put 方法用于将数据填充到 Buffer 中如 ByteBuffer 中的几个 put 方法 1234567// 填充一个 byte 值publicabstract ByteBuffer put(byteb);// 在指定位置填充一个 int 值publicabstract ByteBuffer put(intindex, byteb);// 将一个数组中的值填充进去publicfinal ByteBuffer put(byte[] src) {...}publicByteBuffer put(byte[] src, intoffset, intlength) {...}上述这些方法需要自己控制 Buffer 大小不能超过 capacity超过会抛 java.nio.BufferOverflowException 异常。 对于 Buffer 来说另一个常见的操作中就是我们要将来自 Channel 的数据填充到 Buffer 中在系统层面上这个操作我们称为读操作因为数据是从外部文件或网络等读到内存中。 1intnum channel.read(buf);上述方法会返回从 Channel 中读入到 Buffer 的数据大小。 提取 Buffer 中的值 前面介绍了写操作每写入一个值position 的值都需要加 1所以 position 最后会指向最后一次写入的位置的后面一个如果 Buffer 写满了那么 position 等于 capacityposition 从 0 开始。 如果要读 Buffer 中的值需要切换模式从写入模式切换到读出模式。注意通常在说 NIO 的读操作的时候我们说的是从 Channel 中读数据到 Buffer 中对应的是对 Buffer 的写入操作初学者需要理清楚这个。 调用 Buffer 的 flip() 方法可以进行模式切换。其实这个方法也就是设置了一下 position 和 limit 值罢了。 123456publicfinal Buffer flip() {    limit position; // 将 limit 设置为实际写入的数据数量    position 0;// 重置 position 为 0    mark -1;// mark 之后再说    returnthis;}对应写入操作的一系列 put 方法读操作提供了一系列的 get 方法 123456// 根据 position 来获取数据publicabstract byte get();// 获取指定位置的数据publicabstract byte get(intindex);// 将 Buffer 中的数据写入到数组中publicByteBuffer get(byte[] dst)附一个经常使用的方法 1newString(buffer.array()).trim();当然了除了将数据从 Buffer 取出来使用更常见的操作是将我们写入的数据传输到 Channel 中如通过 FileChannel 将数据写入到文件中通过 SocketChannel 将数据写入网络发送到远程机器等。对应的这种操作我们称之为写操作。 1intnum channel.write(buf);mark() reset() 除了 position、limit、capacity 这三个基本的属性外还有一个常用的属性就是 mark。 mark 用于临时保存 position 的值每次调用 mark() 方法都会将 mark 设值为当前的 position便于后续需要的时候使用。 1234publicfinal Buffer mark() {    mark position;    returnthis;}那到底什么时候用呢考虑以下场景我们在 position 为 5 的时候先 mark() 一下然后继续往下读读到第 10 的时候我想重新回到 position 为 5 的地方重新来一遍那只要调一下 reset() 方法position 就回到 5 了。 1234567publicfinal Buffer reset() {    intm mark;    if(m 0)        thrownew InvalidMarkException();    position m;    returnthis;}rewind() clear() compact() rewind()会重置 position 为 0通常用于重新从头读写 Buffer。 12345publicfinal Buffer rewind() {    position 0;    mark -1;    returnthis;}clear()有点重置 Buffer 的意思相当于重新实例化了一样。 通常我们会先填充 Buffer然后从 Buffer 读取数据之后我们再重新往里填充新的数据我们一般在重新填充之前先调用 clear()。 123456publicfinal Buffer clear() {    position 0;    limit capacity;    mark -1;    returnthis;}compact()和 clear() 一样的是它们都是在准备往 Buffer 填充新的数据之前调用。 前面说的 clear() 方法会重置几个属性但是我们要看到clear() 方法并不会将 Buffer 中的数据清空只不过后续的写入会覆盖掉原来的数据也就相当于清空了数据了。 而 compact() 方法有点不一样调用这个方法以后会先处理还没有读取的数据也就是 position 到 limit 之间的数据还没有读过的数据先将这些数据移到左边然后在这个基础上再开始写入。很明显此时 limit 还是等于 capacityposition 指向原来数据的右边。 Channel 所有的 NIO 操作始于通道通道是数据来源或数据写入的目的地主要地我们将关心 java.nio 包中实现的以下几个 ChannelFileChannel文件通道用于文件的读和写DatagramChannel用于 UDP 连接的接收和发送SocketChannel把它理解为 TCP 连接通道简单理解就是 TCP 客户端ServerSocketChannelTCP 对应的服务端用于监听某个端口进来的请求 这里不是很理解这些也没关系后面介绍了代码之后就清晰了。还有我们最应该关注也是后面将会重点介绍的是 SocketChannel 和 ServerSocketChannel。 Channel 经常翻译为通道类似 IO 中的流用于读取和写入。它与前面介绍的 Buffer 打交道读操作的时候将 Channel 中的数据填充到 Buffer 中而写操作时将 Buffer 中的数据写入到 Channel 中。至少读者应该记住一点这两个方法都是 channel 实例的方法。 FileChannel 我想文件操作对于大家来说应该是最熟悉的不过我们在说 NIO 的时候其实 FileChannel 并不是关注的重点。而且后面我们说非阻塞的时候会看到FileChannel 是不支持非阻塞的。 这里算是简单介绍下常用的操作吧感兴趣的读者瞄一眼就是了。 初始化 12FileInputStream inputStream newFileInputStream(newFile(/data.txt));FileChannel fileChannel inputStream.getChannel();当然了我们也可以从 RandomAccessFile#getChannel 来得到 FileChannel。 读取文件内容 123ByteBuffer buffer ByteBuffer.allocate(1024);intnum fileChannel.read(buffer);前面我们也说了所有的 Channel 都是和 Buffer 打交道的。 写入文件内容 12345678ByteBuffer buffer ByteBuffer.allocate(1024);buffer.put(随机写入一些内容到 Buffer 中.getBytes());// Buffer 切换为读模式buffer.flip();while(buffer.hasRemaining()) {    // 将 Buffer 中的内容写入文件    fileChannel.write(buffer);}SocketChannel 我们前面说了我们可以将 SocketChannel 理解成一个 TCP 客户端。虽然这么理解有点狭隘因为我们在介绍 ServerSocketChannel 的时候会看到另一种使用方式。 打开一个 TCP 连接 1SocketChannel socketChannel SocketChannel.open(newInetSocketAddress(https://www.javadoop.com,80));当然了上面的这行代码等价于下面的两行 1234// 打开一个通道SocketChannel socketChannel SocketChannel.open();// 发起连接socketChannel.connect(newInetSocketAddress(https://www.javadoop.com,80));SocketChannel 的读写和 FileChannel 没什么区别就是操作缓冲区。 1234567// 读取数据socketChannel.read(buffer);// 写入数据到网络连接中while(buffer.hasRemaining()) {    socketChannel.write(buffer);  }不要在这里停留太久先继续往下走。 ServerSocketChannel 之前说 SocketChannel 是 TCP 客户端这里说的 ServerSocketChannel 就是对应的服务端。 ServerSocketChannel 用于监听机器端口管理从这个端口进来的 TCP 连接。 123456789// 实例化ServerSocketChannel serverSocketChannel ServerSocketChannel.open();// 监听 8080 端口serverSocketChannel.socket().bind(newInetSocketAddress(8080));while(true) {    // 一旦有一个 TCP 连接进来就对应创建一个 SocketChannel 进行处理    SocketChannel socketChannel serverSocketChannel.accept();}这里我们可以看到 SocketChannel 的第二个实例化方式到这里我们应该能理解 SocketChannel 了它不仅仅是 TCP 客户端它代表的是一个网络通道可读可写。 ServerSocketChannel 不和 Buffer 打交道了因为它并不实际处理数据它一旦接收到请求后实例化 SocketChannel之后在这个连接通道上的数据传递它就不管了因为它需要继续监听端口等待下一个连接。 DatagramChannel UDP 和 TCP 不一样DatagramChannel 一个类处理了服务端和客户端。 科普一下UDP 是面向无连接的不需要和对方握手不需要通知对方就可以直接将数据包投出去至于能不能送达它是不知道的监听端口 123456DatagramChannel channel DatagramChannel.open();channel.socket().bind(newInetSocketAddress(9090));ByteBuffer buf ByteBuffer.allocate(48);buf.clear();channel.receive(buf);发送数据 123456789String newData New String to write to file...                     System.currentTimeMillis();ByteBuffer buf ByteBuffer.allocate(48);buf.clear();buf.put(newData.getBytes());buf.flip();intbytesSent channel.send(buf, newInetSocketAddress(jenkov.com,80));Selector NIO 三大组件就剩 Selector 了Selector 建立在非阻塞的基础之上大家经常听到的 多路复用 在 Java 世界中指的就是它用于实现一个线程管理多个 Channel。 读者在这一节不能消化 Selector 也没关系因为后续在介绍非阻塞 IO 的时候还得说到这个这里先介绍一些基本的接口操作。 首先我们开启一个 Selector。你们爱翻译成选择器也好多路复用器也好。 1Selector selector Selector.open();将 Channel 注册到 Selector 上。前面我们说了Selector 建立在非阻塞模式之上所以注册到 Selector 的 Channel 必须要支持非阻塞模式FileChannel 不支持非阻塞我们这里讨论最常见的 SocketChannel 和 ServerSocketChannel。 1234// 将通道设置为非阻塞模式因为默认都是阻塞模式的channel.configureBlocking(false);// 注册SelectionKey key channel.register(selector, SelectionKey.OP_READ);register 方法的第二个 int 型参数使用二进制的标记位用于表明需要监听哪些感兴趣的事件共以下四种事件 SelectionKey.OP_READ对应 00000001通道中有数据可以进行读取SelectionKey.OP_WRITE对应 00000100可以往通道中写入数据SelectionKey.OP_CONNECT对应 00001000成功建立 TCP 连接SelectionKey.OP_ACCEPT对应 00010000接受 TCP 连接 我们可以同时监听一个 Channel 中的发生的多个事件比如我们要监听 ACCEPT 和 READ 事件那么指定参数为二进制的 00010001 即十进制数值 17 即可。 注册方法返回值是 SelectionKey 实例它包含了 Channel 和 Selector 信息也包括了一个叫做 Interest Set 的信息即我们设置的我们感兴趣的正在监听的事件集合。 调用 select() 方法获取通道信息。用于判断是否有我们感兴趣的事件已经发生了。 Selector 的操作就是以上 3 步这里来一个简单的示例大家看一下就好了。之后在介绍非阻塞 IO 的时候会演示一份可执行的示例代码。 123456789101112131415161718192021222324252627282930313233Selector selector Selector.open();channel.configureBlocking(false);SelectionKey key channel.register(selector, SelectionKey.OP_READ);while(true) {  // 判断是否有事件准备好  intreadyChannels selector.select();  if(readyChannels 0)continue;  // 遍历  SetSelectionKey selectedKeys selector.selectedKeys();  IteratorSelectionKey keyIterator selectedKeys.iterator();  while(keyIterator.hasNext()) {    SelectionKey key keyIterator.next();    if(key.isAcceptable()) {        // a connection was accepted by a ServerSocketChannel.    }elseif (key.isConnectable()) {        // a connection was established with a remote server.    }elseif (key.isReadable()) {        // a channel is ready for reading    }elseif (key.isWritable()) {        // a channel is ready for writing    }    keyIterator.remove();  }}小结 到此为止介绍了 Buffer、Channel 和 Selector 的常见接口。 Buffer 和数组差不多它有 position、limit、capacity 几个重要属性。put() 一下数据、flip() 切换到读模式、然后用 get() 获取数据、clear() 一下清空数据、重新回到 put() 写入数据。 Channel 基本上只和 Buffer 打交道最重要的接口就是 channel.read(buffer) 和 channel.write(buffer)。 Selector 用于实现非阻塞 IO这里仅仅介绍接口使用后续请关注非阻塞 IO 的介绍。
http://www.pierceye.com/news/101399/

相关文章:

  • 企业网站的建设要注意哪些方面免费字体下载网站
  • 建怎样的网站挣钱快网站怎么做微博认证吗
  • 衡水做网站改版网站开发教程流程
  • 鞍山网站制作人才招聘广州网站优化步骤
  • 网站使用微信支付宁国网络推广
  • 成都网站建设六六济南网站制作公司
  • c 网站开发技术链友咨询
  • 手机网站推荐怎样做网站建设
  • 下载学校网站模板下载安装住建部官网查询
  • 模板网站新增备案两次都未通过网站也打不开电子商务网站建设实训报告文章
  • 做标签网站是干嘛的帐号售卖网站建设
  • 建设市民中心网站wordpress只显示标题插件
  • 网站备案的好处鲜花网站建设论文百度文库
  • 网站建设运营策划石家庄住房和建设局网站
  • 网站制作器公司网站虚假宣传但网站不是我做的
  • 大淘客网站建设婚庆网页设计作品dw
  • 嘉兴网站关键词优化后端开发流程
  • 有网络网站打不开怎么回事培训机构推广
  • 淄博网站建设优化珍云网站可信图标
  • 大连外贸网站建设江门营销网站建设
  • 县网站建设方案怎么做付费的小说网站
  • 企业公众号以及网站建设我想做个网站
  • 网站设为主页功能怎么做怎样制作h5
  • 网站的内容与功能设计微信公众平台小程序二维码怎么生成
  • 西安网站快速优化重庆明建网络科技有限公司干啥的
  • 广州市天河区门户网站软件制作公司
  • 做网站前期创建文件夹博罗高端网站建设价格
  • 襄阳网站建设价格淄博网站推广价格
  • 网站推广的软件六安网站制作哪里有
  • 大型门户网站模板wordpress有哪些小工具