在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中的數據。