在JAVA中的流分为字节流或字符流,一般来说采用字符流处理起来更加方便。字节流处理起来相对麻烦,SocketChannel中将数据读取到ByteBuffer中,如何取出完整的一行数据(使用CRLF分隔)?

例如:

Socket收到的内容为:

1234567890CRLF

0123456789CRLF

注意:CRLF为回车换行符号

如果使用 SocketChannel.read(ByteBuffer buff)读取数据,如果buff的capatity为12, 则第一次读取的数据为 “1234567890CRLF” 刚好为一行,但是如果buff的capatity小于12,则要读取两次以上才能读到CRLF回车换行符号。如果buff.capatity大于12,则会读取到第二行的数据,那么下次读取操作时,如何处理第一次多读到的数据?  这个问题与 "回推流" 类似。

为解决此问题,并实现与“回推流”类似的功能。建立如下的处理模型

Source、Cursor接口实现从Channel中读取字节,并实现回推功能。

Source.ready() 函数返回已经从Channel中读取的数据。如果Buffer中还有数据,则返回Buffer中剩余的自己数,如果Buffer中的字节都已经读取了,则重新从Channel中读取数据到Buffer中。如果没有数据可以读取了,则返回-1;

Source.ready(byte[] dst, int off, int len) 函数重Buffer中读取数据到 dst中。

Source.reset(int len) 函数在Buffer层面上实现回退,即设置Buffer.position。

Cursor接口对Source接口进一步封装,同时提供push函数扩展了reset的回推功能。

Cursor.push(byte[] src, int off, int len) 将byte[]中的数据回推到Cursor中,下次读取操作时将把push进去的数据读取出来。

Consumer接口使用consumer函数从Cursor中读取数据,并进行相应的处理。根据不同的业务逻辑继承Consumer接口处理Cursor中的数据。

Java SocketChannel 读取ByteBuffer字节的处理模型的更多相关文章

  1. 图解java中的bytebuffer

    因何而写 网上关于bytebuffer的文章真的很多,为何在此还要写一篇呢?主要是基于以下几点考虑 很多人在使用t-io时,还不会bytebuffer,只会照着t-io提供的例子照猫画虎,不利于灵活运 ...

  2. 读取ByteBuffer有效的数据

    转:https://zhidao.baidu.com/question/427134449349230532.html说道 ByteBuffer的缓冲区,就需要知道缓冲区的的三个状态1)capacit ...

  3. Java 运行时数据区和内存模型

    运行时数据区是指对 JVM 运行过程中涉及到的内存根据功能.目的进行的划分,而内存模型可以理解为对内存进行存取操作的过程定义.总是有人望文生义的将前者描述为 "Java 内存模型" ...

  4. Java将文件转为字节数组

    Java将文件转为字节数组 关键字:文件,文件流,字节流,字节数组,二进制 摘要:最近工作中碰到的需求是,利用http传输二进制数据到服务器对应接口,需要传输userId, file(加密后)等一系列 ...

  5. java中读取文件以及向文件中追加数据的总结

    package gys; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; imp ...

  6. Java InputStream读取网络响应Response数据的方法

    Java InputStream读取数据问题 原理讲解 1. 关于InputStream.read()     在从数据流里读取数据时,为图简单,经常用InputStream.read()方法.这个方 ...

  7. 分享非常有用的Java程序(关键代码)(八)---Java InputStream读取网络响应Response数据的方法!(重要)

    原文:分享非常有用的Java程序(关键代码)(八)---Java InputStream读取网络响应Response数据的方法!(重要) Java InputStream读取数据问题 ======== ...

  8. Java IO 转换流 字节转字符流

    Java IO 转换流 字节转字符流 @author ixenos 字节流 输入字节流:---------| InputStream 所有输入字节流的基类. 抽象类.------------| Fil ...

  9. 【转载】java InputStream读取数据问题

    原文链接:http://www.cnblogs.com/MyFavorite/archive/2010/10/19/1855758.html 1. 关于InputStream.read()     在 ...

随机推荐

  1. Angular 4 自定义组件封装遇见的一些事儿

    你用Angular 吗? 一.介绍 说说封装Angular 组建过程中遇见的一些问题和感悟.用久了Angular,就会遇见很多坑,许多基于Angular开发的框架最喜欢做的事情就是封装组件,然后复用. ...

  2. c#动态编译并执行字符串

    比较简单,步骤是这样的 string -> compiler -> assembly -> reflection -> execution 直接上代码: using Syste ...

  3. 在CMainFrame里使用定时器是有讲究的

    设置定时器函数:SetTimer 单位毫秒 销毁定时器函数:KillTimer 消息:WM_TIMER 注意事项: (1)不要在构造函数里设置定时器. (2)不要在析构函数里销毁定时器. 原因:构造函 ...

  4. Linux 中su和sudo命令的几个注意点

    1 su与su - 的区别 1.1命令说明 su对应是是no-login shell的方式进行账号登陆,命令行的变量配置还是切换账号前的变量. su-对应的是login shell的方式进行账号登陆, ...

  5. PDO prepare预处理语句

    预处理语句 $dsn="mysql:host=localhost;dbname=emp"; try{ $pdo=new PDO($dsn,'root','root'); }catc ...

  6. KVM详情

    KVM介绍 Kernel-based Virtual Machine的简称,是一个开源的系统虚拟化模块,自Linux 2.6.20之后集成在Linux的各个主要发行版本中.它使用Linux自身的调度器 ...

  7. Tomcat就是这么简单

    什么是Tomcat Tomcat简单的说就是一个运行JAVA的网络服务器,底层是Socket的一个程序,它也是JSP和Serlvet的一个容器. 为什么我们需要用到Tomcat 如果你学过html,c ...

  8. spring boot 中实现兼容不同的请求类型的方法。

    比如一个接口,既想实现请求参数是application/json,又想实现form提交,改怎么做呢?用postman去测试,发现不可能做到两全其美. 我有一个方法,就是不用requestbody,也可 ...

  9. HashMap原理总结

    来总结一下HashMap的原理 1.HashMap当中有一个内部类,它叫Node,然后这个Node呢,它其实是实现了Map.Entry接口,这个接口当中有几个抽象的方法和几个具体的方法.其中Map.E ...

  10. Hadoop学习笔记三

    一.设置HDFS不进行权限检查 默认的HDFS上的文件类似于Linux中的文件,是有权限的.例如test用户创建的文件,root用户如果没有写权限,则不能进行删除. 有2种办法进行修改,修改文件的权限 ...