/**
* A decoder that splits the received {@link ByteBuf}s by the fixed number
* of bytes. For example, if you received the following four fragmented packets:
*
* +---+----+------+----+
* | A | BC | DEFG | HI |
* +---+----+------+----+
*
* A {@link FixedLengthFrameDecoder}{@code (3)} will decode them into the
* following three packets with the fixed length:
* 如果固定长度为3,上面数据包会被解析成如下:
*
public class LineBasedFrameDecoder extends ByteToMessageDecoder {
/** Maximum length of a frame we're willing to decode. */
private final int maxLength;// 最大长度
/** Whether or not to throw an exception as soon as we exceed maxLength. */
private final boolean failFast;//是否快速失败
private final boolean stripDelimiter;//解析的数据包时候带换行符,false带,true不带
/** True if we're discarding input because we're already over maxLength. */
private boolean discarding;//超过最大长度时候抛弃
private int discardedBytes;//抛弃的字节数
/**
* Creates a new decoder.
* @param maxLength the maximum length of the decoded frame.
* A {@link TooLongFrameException} is thrown if
* the length of the frame exceeds this value.
*/
public LineBasedFrameDecoder(final int maxLength) {
this(maxLength, true, false);
}
/**
* Creates a new decoder.
* @param maxLength the maximum length of the decoded frame.
* A {@link TooLongFrameException} is thrown if
* the length of the frame exceeds this value.
* @param stripDelimiter whether the decoded frame should strip out the
* delimiter or not
* @param failFast If true, a {@link TooLongFrameException} is
* thrown as soon as the decoder notices the length of the
* frame will exceed maxFrameLength regardless of
* whether the entire frame has been read.
* If false, a {@link TooLongFrameException} is
* thrown after the entire frame that exceeds
* maxFrameLength has been read.
*/
public LineBasedFrameDecoder(final int maxLength, final boolean stripDelimiter, final boolean failFast) {
this.maxLength = maxLength;
this.failFast = failFast;
this.stripDelimiter = stripDelimiter;
}
@Override
protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception {
Object decoded = decode(ctx, in);
if (decoded != null) {
out.add(decoded);
}
}
/**
* Create a frame out of the {@link ByteBuf} and return it.
*
* @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to
* @param buffer the {@link ByteBuf} from which to read data
* @return frame the {@link ByteBuf} which represent the frame or {@code null} if no frame could
* be created.
*/
protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
final int eol = findEndOfLine(buffer);//寻找行的结尾,\n或者\r\n
if (!discarding) {//非丢弃模式
if (eol >= 0) {
final ByteBuf frame;
final int length = eol - buffer.readerIndex();//endofline-readerIndex即为可读字节
final int delimLength = buffer.getByte(eol) == '\r'? 2 : 1;//分隔符长度,2或者1
if (length > maxLength) {
buffer.readerIndex(eol + delimLength);//当可读字节大于行最大长度,则移动readerIndex到下一个可读区域
fail(ctx, length);//传播异常
return null;//返回null表示当前什么也没有解析
}
if (stripDelimiter) {//是否跳过分隔符
frame = buffer.readRetainedSlice(length);//解析数据不包含分隔符
buffer.skipBytes(delimLength);
} else {
frame = buffer.readRetainedSlice(length + delimLength);//解析数据包含分隔符
}
return frame;//返回解析数据包
} else {//readerIndex和writerIndex没有换行符
final int length = buffer.readableBytes();
if (length > maxLength) {//可读长度大于最大行长度
discardedBytes = length;//丢弃字节长度
buffer.readerIndex(buffer.writerIndex());//读指针直接移到写指针
discarding = true;//进入丢弃模式
if (failFast) {//是否快速失败,传播异常
fail(ctx, "over " + discardedBytes);
}
}
return null;
}
} else {//丢弃模式
if (eol >= 0) {
final int length = discardedBytes + eol - buffer.readerIndex();//丢弃长度=discardedBytes +当前可读长度
final int delimLength = buffer.getByte(eol) == '\r'? 2 : 1;
buffer.readerIndex(eol + delimLength);//移动指针到分隔符之后
discardedBytes = 0;//重置丢弃长度
discarding = false;//进入非丢弃模式
if (!failFast) {
fail(ctx, length);
}
} else {//没有找到分隔符,直接移动readerIndex到writerIndex
discardedBytes += buffer.readableBytes();
buffer.readerIndex(buffer.writerIndex());
}
return null;
}
}
private void fail(final ChannelHandlerContext ctx, int length) {
fail(ctx, String.valueOf(length));
}
四、分隔符解码器DelimiterBasedFrameDecoder
图片.png
public class DelimiterBasedFrameDecoder extends ByteToMessageDecoder {
private final ByteBuf[] delimiters;
private final int maxFrameLength;
private final boolean stripDelimiter;
private final boolean failFast;
private boolean discardingTooLongFrame;
private int tooLongFrameLength;
/** Set only when decoding with "\n" and "\r\n" as the delimiter. */
private final LineBasedFrameDecoder lineBasedDecoder;
public DelimiterBasedFrameDecoder(int maxFrameLength, ByteBuf delimiter) {
this(maxFrameLength, true, delimiter);
}
public DelimiterBasedFrameDecoder(
int maxFrameLength, boolean stripDelimiter, ByteBuf delimiter) {
this(maxFrameLength, stripDelimiter, true, delimiter);
}
public DelimiterBasedFrameDecoder(
int maxFrameLength, boolean stripDelimiter, boolean failFast,
ByteBuf delimiter) {
this(maxFrameLength, stripDelimiter, failFast, new ByteBuf[] {
delimiter.slice(delimiter.readerIndex(), delimiter.readableBytes())});
}
public DelimiterBasedFrameDecoder(int maxFrameLength, ByteBuf... delimiters) {
this(maxFrameLength, true, delimiters);
}
public DelimiterBasedFrameDecoder(
int maxFrameLength, boolean stripDelimiter, ByteBuf... delimiters) {
this(maxFrameLength, stripDelimiter, true, delimiters);
}
//构造方法
public DelimiterBasedFrameDecoder(
int maxFrameLength, boolean stripDelimiter, boolean failFast, ByteBuf... delimiters) {
validateMaxFrameLength(maxFrameLength);
if (delimiters == null) {
throw new NullPointerException("delimiters");
}
if (delimiters.length == 0) {
throw new IllegalArgumentException("empty delimiters");
}
if (isLineBased(delimiters) && !isSubclass()) {//初始化行解码器
lineBasedDecoder = new LineBasedFrameDecoder(maxFrameLength, stripDelimiter, failFast);
this.delimiters = null;
} else {
this.delimiters = new ByteBuf[delimiters.length];
for (int i = 0; i < delimiters.length; i ++) {
ByteBuf d = delimiters[i];
validateDelimiter(d);
this.delimiters[i] = d.slice(d.readerIndex(), d.readableBytes());
}
lineBasedDecoder = null;
}
this.maxFrameLength = maxFrameLength;
this.stripDelimiter = stripDelimiter;
this.failFast = failFast;
}
/**判断分隔符是否是 "\n" and "\r\n",是则为行解码器 */
private static boolean isLineBased(final ByteBuf[] delimiters) {
if (delimiters.length != 2) {
return false;
}
ByteBuf a = delimiters[0];
ByteBuf b = delimiters[1];
if (a.capacity() < b.capacity()) {
a = delimiters[1];
b = delimiters[0];
}
return a.capacity() == 2 && b.capacity() == 1
&& a.getByte(0) == '\r' && a.getByte(1) == '\n'
&& b.getByte(0) == '\n';
}
@Override
protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception {
Object decoded = decode(ctx, in);
if (decoded != null) {
out.add(decoded);
}
}
protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
if (lineBasedDecoder != null) {//行解码器不为空,则使用 行解码器解码
return lineBasedDecoder.decode(ctx, buffer);
}
// Try all delimiters and choose the delimiter which yields the shortest frame.
int minFrameLength = Integer.MAX_VALUE;
ByteBuf minDelim = null;
for (ByteBuf delim: delimiters) {//找到最小分隔符
int frameLength = indexOf(buffer, delim);
if (frameLength >= 0 && frameLength < minFrameLength) {
minFrameLength = frameLength;
minDelim = delim;
}
}
if (minDelim != null) {//找到分隔符
int minDelimLength = minDelim.capacity();
ByteBuf frame;
if (discardingTooLongFrame) {//是否丢弃模式
discardingTooLongFrame = false;//重置丢弃模式为false
buffer.skipBytes(minFrameLength + minDelimLength);//跳过
int tooLongFrameLength = this.tooLongFrameLength;
this.tooLongFrameLength = 0;
if (!failFast) {//是否已快速失败
fail(tooLongFrameLength);
}
return null;
}
//最小分隔符分割的数据包仍大于最大数据包
if (minFrameLength > maxFrameLength) {
// Discard read frame.
buffer.skipBytes(minFrameLength + minDelimLength);//跳过
fail(minFrameLength);//传播异常
return null;
}
if (stripDelimiter) {//是否包含分隔符
frame = buffer.readRetainedSlice(minFrameLength);
buffer.skipBytes(minDelimLength);
} else {
frame = buffer.readRetainedSlice(minFrameLength + minDelimLength);
}
return frame;
} else {//没有找到分隔符时
if (!discardingTooLongFrame) {//非丢弃状态
if (buffer.readableBytes() > maxFrameLength) {//可读数据大于允许最大数据包
// Discard the content of the buffer until a delimiter is found.
tooLongFrameLength = buffer.readableBytes();
buffer.skipBytes(buffer.readableBytes());//直接跳过可读数据
discardingTooLongFrame = true;//进去丢弃状态
if (failFast) {//是否快速失败
fail(tooLongFrameLength);
}
}
} else {//丢弃状态
// Still discarding the buffer since a delimiter is not found.
tooLongFrameLength += buffer.readableBytes();//记录丢弃的字节数
buffer.skipBytes(buffer.readableBytes());//直接跳过可读数据
}
return null;
}
}
private void fail(long frameLength) {
if (frameLength > 0) {
throw new TooLongFrameException(
"frame length exceeds " + maxFrameLength +
": " + frameLength + " - discarded");
} else {
throw new TooLongFrameException(
"frame length exceeds " + maxFrameLength +
" - discarding");
}
}
/**
* Returns the number of bytes between the readerIndex of the haystack and
* the first needle found in the haystack. -1 is returned if no needle is
* found in the haystack.
*/
private static int indexOf(ByteBuf haystack, ByteBuf needle) {
for (int i = haystack.readerIndex(); i < haystack.writerIndex(); i ++) {
int haystackIndex = i;
int needleIndex;
for (needleIndex = 0; needleIndex < needle.capacity(); needleIndex ++) {
if (haystack.getByte(haystackIndex) != needle.getByte(needleIndex)) {
break;
} else {
haystackIndex ++;
if (haystackIndex == haystack.writerIndex() &&
needleIndex != needle.capacity() - 1) {
return -1;
}
}
}
if (needleIndex == needle.capacity()) {
// Found the needle from the haystack!
return i - haystack.readerIndex();
}
}
return -1;
}
private static void validateDelimiter(ByteBuf delimiter) {
if (delimiter == null) {
throw new NullPointerException("delimiter");
}
if (!delimiter.isReadable()) {
throw new IllegalArgumentException("empty delimiter");
}
}
private static void validateMaxFrameLength(int maxFrameLength) {
if (maxFrameLength <= 0) {
throw new IllegalArgumentException(
"maxFrameLength must be a positive integer: " +
maxFrameLength);
}
}
}
好久不来iteye,今天又来看看,哈哈,今天碰到在编码时,反射中会抛出
Illegal overloaded getter method with ambiguous type for propert这么个东东,从字面意思看,是反射在获取getter时迷惑了,然后回想起java在boolean值在生成getter时,分别有is和getter,也许我们的反射对象中就有is开头的方法迷惑了jdk,
泛型
在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,任意化的缺点就是要实行强制转换,这种强制转换可能会带来不安全的隐患
泛型的特点:消除强制转换 确保类型安全 向后兼容
简单泛型的定义:
泛型:就是在类中将其模糊化,在创建对象的时候再具体定义
class fan
安装lua_nginx_module 模块
lua_nginx_module 可以一步步的安装,也可以直接用淘宝的OpenResty
Centos和debian的安装就简单了。。
这里说下freebsd的安装:
fetch http://www.lua.org/ftp/lua-5.1.4.tar.gz
tar zxvf lua-5.1.4.tar.gz
cd lua-5.1.4
ma
public class IsAccendListRecursive {
/*递归判断数组是否升序
* if a Integer array is ascending,return true
* use recursion
*/
public static void main(String[] args){
IsAccendListRecursiv
function init() {
var tt = document.getElementById("tt");
var childNodes = tt.childNodes[0].childNodes;
var level = 0;
for (var i = 0; i < childNodes.length; i++) {
在安装hadoop时,执行JPS出现下面错误
[slave16][email protected]:/tmp/hsperfdata_hdfs# jps
Error occurred during initialization of VM
java.lang.Error: Properties init: Could not determine current working