Java SocketChannel 讀取ByteBuffer字節的處理模型


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM