聽 聽 聽 聽鏌ョ湅 Mina 瀵?TextLineCodec 鐨勫疄鐜版簮鐮佷細鍙戠幇锛屾牴鎹崲琛岀瑙g爜鐨勬秷鎭犻粯璁ゆ渶澶ч暱搴︽槸 1024锛?鐩稿綋浜庣紦鍐插尯鏈€澶ц兘瀛樻斁 1K 鐨勬暟鎹€傛墍浠ヤ娇鐢ㄦ椂锛屽缓璁皟鏁村弬鏁颁负 2K锛?/p>
聽 聽 聽 聽鏍规嵁鎴戜滑鑷繁瀹氫箟鐨勬枃鏈崲琛岀鍙婄紪鐮佹牸寮忕紪瑙g爜锛?鍒欓渶瑕佹妸瀹冧滑浣滀负鍙傛暟浼犻€掔粰缂栬В鐮佸櫒锛涘畬鏁翠唬鐮佸涓嬶細
瑙g爜鍣?/p>
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
public class MyCodecDecoderII implements ProtocolDecoder {
private Charset charset; // 缂栫爜鏍煎紡
private String delimiter; // 鏂囨湰鍒嗛殧绗?
private IoBuffer delimBuf; // 鏂囨湰鍒嗗壊绗﹀尮閰嶇殑鍙橀噺
// 瀹氫箟甯搁噺鍊硷紝浣滀负姣忎釜IoSession涓繚瀛樿В鐮佷换鍔$殑key鍊?
private static String CONTEXT = MyCodecDecoderII.class.getName()
+ ".context";
// 鏋勯€犲嚱鏁帮紝蹇呴』鎸囧畾Charset鍜屾枃鏈垎闅旂
public MyCodecDecoderII(Charset charset, String delimiter) {
this.charset = charset;
this.delimiter = delimiter;
}
public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)
throws Exception {
Context ctx = getContext(session);
// 濡傛灉鏂囨湰鎹㈣绗︽湭鎸囧畾锛屼娇鐢ㄩ粯璁ゅ€?
if (delimiter == null || "".equals(delimiter)) {
delimiter = "\r\n";
}
if (charset == null) {
charset = Charset.forName("utf-8");
}
decodeNormal(ctx, in, out);
}
// 浠嶪oSession涓幏鍙朇ontext瀵硅薄
private Context getContext(IoSession session) {
Context ctx;
ctx = (Context) session.getAttribute(CONTEXT);
if (ctx == null) {
ctx = new Context();
session.setAttribute(CONTEXT, ctx);
}
return ctx;
}
// 瑙g爜
private void decodeNormal(Context ctx, IoBuffer in,
ProtocolDecoderOutput out) throws CharacterCodingException {
// 鍙栧嚭鏈畬鎴愪换鍔′腑宸茬粡鍖归厤鐨勬枃鏈崲琛岀鐨勪釜鏁?
int matchCount = ctx.getMatchCount();
// 璁剧疆鍖归厤鏂囨湰鎹㈣绗︾殑IoBuffer鍙橀噺
if (delimBuf == null) {
IoBuffer tmp = IoBuffer.allocate(2).setAutoExpand(true);
tmp.putString(delimiter, charset.newEncoder());
tmp.flip();
delimBuf = tmp;
}
int oldPos = in.position(); // 瑙g爜鐨処oBuffer涓暟鎹殑鍘熷淇℃伅
int oldLimit = in.limit();
while (in.hasRemaining()) { // 鍙橀噺瑙g爜鐨処oBuffer
byte b = in.get();
if (delimBuf.get(matchCount) == b) { // 鍖归厤绗琺atchCount浣嶆崲琛岀鎴愬姛
matchCount++;
if (matchCount == delimBuf.limit()) { // 褰撳墠鍖归厤鍒板瓧鑺備釜鏁颁笌鏂囨湰鎹㈣绗﹀瓧鑺備釜鏁扮浉鍚岋紝鍖归厤缁撴潫
int pos = in.position(); // 鑾峰緱褰撳墠鍖归厤鍒扮殑position锛坧osition鍓嶆墍鏈夋暟鎹湁鏁堬級
in.limit(pos);
in.position(oldPos); // position鍥炲埌鍘熷浣嶇疆
ctx.append(in); // 杩藉姞鍒癈ontext瀵硅薄鏈畬鎴愭暟鎹悗闈?
in.limit(oldLimit); // in涓尮閰嶇粨鏉熷悗鍓╀綑鏁版嵁
in.position(pos);
IoBuffer buf = ctx.getBuf();
buf.flip();
buf.limit(buf.limit() - matchCount);// 鍘绘帀鍖归厤鏁版嵁涓殑鏂囨湰鎹㈣绗?
try {
out.write(buf.getString(ctx.getDecoder())); // 杈撳嚭瑙g爜鍐呭
} finally {
buf.clear(); // 閲婃斁缂撳瓨绌洪棿
}
oldPos = pos;
matchCount = 0;
}
} else {
// 濡傛灉matchCount==0锛屽垯缁х画鍖归厤
// 濡傛灉matchCount>0锛岃鏄庢病鏈夊尮閰嶅埌鏂囨湰鎹㈣绗︾殑涓殑鍓嶄竴涓尮閰嶆垚鍔熷瓧鑺傜殑涓嬩竴涓瓧鑺傦紝
// 璺宠浆鍒板尮閰嶅け璐ュ瓧绗﹀锛屽苟缃甿atchCount=0锛岀户缁尮閰?
in.position(in.position() - matchCount);
matchCount = 0; // 鍖归厤鎴愬姛鍚庯紝matchCount缃┖
}
}
// 鎶奿n涓湭瑙g爜鍐呭鏀惧洖buf涓?
in.position(oldPos);
ctx.append(in);
ctx.setMatchCount(matchCount);
}
public void dispose(IoSession session) throws Exception {
}
public void finishDecode(IoSession session, ProtocolDecoderOutput out)
throws Exception {
}
// 鍐呴儴绫伙紝淇濆瓨IoSession瑙g爜鏃舵湭瀹屾垚鐨勪换鍔?
private class Context {
private CharsetDecoder decoder;
private IoBuffer buf; // 淇濆瓨鐪熷疄瑙g爜鍐呭
private int matchCount = 0; // 鍖归厤鍒扮殑鏂囨湰鎹㈣绗︿釜鏁?
private Context() {
decoder = charset.newDecoder();
buf = IoBuffer.allocate(80).setAutoExpand(true);
}
// 閲嶇疆
public void reset() {
matchCount = 0;
decoder.reset();
}
// 杩藉姞鏁版嵁
public void append(IoBuffer in) {
getBuf().pu