背景:部标GPS通讯底层全部改造成基于Netty服务器实现的,现将Mina的依赖移除,修改过程中有用到缓冲区的读写。现做了如下修改:
原有基于Mina的IoBuffer对字节读写封装代码如下:
1 package com.hns.gps.gw.jt808.protocol; 2 3 import com.hns.gps.gw.jt808.utils.Tools; 4 import org.apache.log4j.Logger; 5 import org.apache.mina.core.buffer.IoBuffer; 6 7 import java.nio.charset.CharacterCodingException; 8 import java.nio.charset.Charset; 9 10 public class MyBuffer { 11 private Logger logger = Logger.getLogger(MyBuffer.class); 12 IoBuffer buff; 13 14 public MyBuffer() { 15 buff.setUseDirectBuffer(false); 16 buff = IoBuffer.allocate(1536); 17 buff.mark(); 18 } 19 20 public MyBuffer(int len) { 21 buff.setUseDirectBuffer(false); 22 buff = IoBuffer.allocate(len); 23 buff.mark(); 24 } 25 26 public MyBuffer(byte[] bytes) { 27 if (bytes.length > 1024) 28 buff = IoBuffer.allocate(bytes.length + 100); 29 else 30 buff = IoBuffer.allocate(1024); 31 buff.mark(); 32 buff.put(bytes); 33 buff.limit(bytes.length); 34 buff.reset(); 35 } 36 public MyBuffer(byte[] bytes, int start, int length) { 37 buff = IoBuffer.allocate(length); 38 buff.mark(); 39 buff.put(bytes, start, length); 40 buff.limit(length); 41 buff.reset(); 42 } 43 44 45 public void clear() { 46 buff.clear(); 47 buff.mark(); 48 } 49 50 public void put(byte a) { 51 buff.put(a); 52 } 53 54 public void put(long a) 55 { 56 buff.putLong(a); 57 } 58 59 public void put(short a) { 60 buff.putShort(a); 61 } 62 63 public void put(byte[] a) { 64 buff.put(a); 65 } 66 67 public boolean hasRemain() { 68 return buff.remaining() > 0; 69 } 70 71 public void put(int a) { 72 buff.putInt(a); 73 } 74 75 public void putShort(int a) { 76 buff.putShort((short) a); 77 } 78 79 public void put(String str) { 80 // US-ASCII 81 82 try { 83 byte[] b = str.getBytes("gbk"); 84 buff.put(b); 85 86 } catch (Exception e) { 87 // logger.error(e.getMessage(), e); 88 } 89 } 90 91 public void putBcd(String str, int length) 92 { 93 byte[] b = BcDToBytes(str,length); 94 buff.put(b); 95 } 96 97 98 public static String BytesToBcd(byte[] bytes, int start, int len) { 99 StringBuilder bcd = new StringBuilder(); 100 for (int m = 0; m < len; m++) { 101 bcd.append(String.format("%02X", bytes[start + m])); 102 } 103 return bcd.toString(); 104 } 105 106 public static byte[] BcDToBytes(String bcd, int len) { 107 bcd = bcd == null ? "" : bcd; 108 while (bcd.length() < len) { 109 bcd = "0" + bcd; 110 } 111 return Tools.HexString2Bytes(bcd); 112 } 113 114 public void put(String str, int len) { 115 byte[] result = new byte[len]; 116 try { 117 byte[] b = str.getBytes("gbk"); 118 119 System.arraycopy(b, 0, result, 0, b.length); 120 121 for (int m = b.length; m < len; m++) { 122 result[m] = 0; 123 } 124 buff.put(result); 125 126 } catch (Exception e) { 127 //logger.error(e.getMessage(), e); 128 } 129 } 130 131 public byte get() { 132 return buff.get(); 133 } 134 135 public byte[] gets(int len) { 136 byte[] data = new byte[len]; 137 buff.get(data); 138 return data; 139 } 140 141 public int getInt() { 142 return buff.getInt(); 143 } 144 145 public short getShort() { 146 return buff.getShort(); 147 } 148 149 public long getLong() { 150 return buff.getLong(); 151 } 152 153 // 将data字节型数据转换为0~65535 (0xFFFF 即 WORD)。 154 public int getUnsignedShort() { 155 short t = buff.getShort(); 156 return t & 0xffff; 157 } 158 159 // 将data字节型数据转换为0~255 (0xFF 即BYTE)。 160 public int getUnsignedByte() { 161 return buff.get() & 0x0FF; 162 } 163 164 public long getUnsignedInt() { 165 return buff.getInt() & 0x0FFFFFFFF; 166 } 167 168 public String getString() { 169 try { 170 String strTemp = buff 171 .getString(Charset.forName("GBK").newDecoder()); 172 return strTemp; 173 } catch (CharacterCodingException e) { 174 e.printStackTrace(); 175 } 176 return ""; 177 } 178 179 public String getString(int len) { 180 try { 181 String strTemp = buff.getString(len, Charset.forName("GBK") 182 .newDecoder()); 183 return strTemp; 184 } catch (CharacterCodingException e) { 185 e.printStackTrace(); 186 gets(len); 187 } 188 return ""; 189 } 190 191 public String getBcdString(int len) { 192 byte[] bytes = this.gets(len); 193 StringBuilder bcd = new StringBuilder(); 194 for (int m = 0; m < len; m++) { 195 bcd.append(String.format("%02X", bytes[m])); 196 } 197 return bcd.toString(); 198 } 199 200 public byte[] array() { 201 int pos = buff.position(); 202 byte[] data = new byte[pos]; 203 buff.reset(); 204 buff.get(data); 205 return data; 206 } 207 208 public static void main(String[] args) { 209 210 IoBuffer ib = IoBuffer.allocate(1024); 211 ib.mark(); 212 ib.put((byte) 128); 213 ib.reset(); 214 // byte b = ib.get(); 215 // int x = b& 0xff; 216 short x = ib.getUnsigned(); 217 218 short y = ib.getUnsigned(0); 219 220 System.out.println("" + x + "," + y); 221 } 222 223 }
后修改成Netty版的ByteBuffer操作实现如下:
1 package com.hns.gps.gw.jt808.protocol; 2 3 import com.hns.gps.gw.jt808.utils.Tools; 4 import io.netty.buffer.ByteBuf; 5 import io.netty.buffer.ByteBufAllocator; 6 import org.apache.log4j.Logger; 7 8 import java.io.UnsupportedEncodingException; 9 import java.nio.charset.Charset; 10 11 /** 12 * ByteBuffer缓冲区,用Netty实现 13 * 14 * @author linys 15 * @create 2018-06-12 16 * @since 1.0.0 17 */ 18 public class ByteBuffer { 19 private Logger logger = Logger.getLogger(ByteBuffer.class); 20 ByteBuf buff; 21 22 public ByteBuffer() { 23 buff = ByteBufAllocator.DEFAULT.ioBuffer(1536); 24 buff.markWriterIndex(); 25 } 26 27 28 public ByteBuffer(int len) { 29 buff = ByteBufAllocator.DEFAULT.ioBuffer(len); 30 buff.markWriterIndex(); 31 } 32 33 34 public ByteBuffer(byte[] bytes) { 35 if (bytes.length > 1024) { 36 buff = ByteBufAllocator.DEFAULT.ioBuffer(bytes.length + 100); 37 } else { 38 buff = ByteBufAllocator.DEFAULT.ioBuffer(1024); 39 } 40 buff.markWriterIndex(); 41 buff.writeBytes(bytes); 42 buff.capacity(bytes.length); 43 } 44 45 public ByteBuffer(byte[] bytes, int start, int length) { 46 buff = ByteBufAllocator.DEFAULT.ioBuffer(length); 47 buff.markWriterIndex(); 48 buff.writeBytes(bytes, start, length); 49 buff.resetWriterIndex(); 50 } 51 52 public void clear() { 53 buff.clear(); 54 buff.resetWriterIndex(); 55 buff.resetReaderIndex(); 56 } 57 58 public void put(byte a) { 59 buff.writeByte(a); 60 } 61 62 public void put(long a) { 63 buff.writeLong(a); 64 } 65 66 public void put(short a) { 67 buff.writeShort(a); 68 } 69 70 public void put(byte[] a) { 71 buff.writeBytes(a); 72 } 73 74 public boolean hasRemain() { 75 return buff.isReadable(); 76 } 77 78 public void put(int a) { 79 buff.writeInt(a); 80 } 81 82 public void put(String str) { 83 // US-ASCII 84 try { 85 byte[] b = str.getBytes("gbk"); 86 buff.writeBytes(b); 87 } catch (UnsupportedEncodingException e) { 88 logger.error(e.getMessage(), e); 89 } 90 } 91 92 public String getBcdString(int len) { 93 byte[] bytes = this.gets(len); 94 StringBuilder bcd = new StringBuilder(); 95 for (int m = 0; m < len; m++) { 96 bcd.append(String.format("%02X", bytes[m])); 97 } 98 return bcd.toString(); 99 } 100 101 public void putBcd(String str, int length) { 102 byte[] b = BcDToBytes(str, length); 103 buff.writeBytes(b); 104 } 105 106 public static byte[] BcDToBytes(String bcd, int len) { 107 bcd = bcd == null ? "" : bcd; 108 while (bcd.length() < len) { 109 bcd = "0" + bcd; 110 } 111 return Tools.HexString2Bytes(bcd); 112 } 113 114 public static String BytesToBcd(byte[] bytes, int start, int len) { 115 StringBuilder bcd = new StringBuilder(); 116 for (int m = 0; m < len; m++) { 117 bcd.append(String.format("%02X", bytes[start + m])); 118 } 119 return bcd.toString(); 120 } 121 122 public void put(String str, int len) { 123 byte[] result = new byte[len]; 124 try { 125 byte[] b = str.getBytes("gbk"); 126 System.arraycopy(b,0, result,0, b.length); 127 for (int m = b.length; m < len; m++) { 128 result[m] = 0; //不够位补0 129 } 130 buff.writeBytes(result); 131 } catch (UnsupportedEncodingException e) { 132 logger.error(e.getMessage(), e); 133 } 134 } 135 136 public byte get() { 137 return buff.readByte(); 138 } 139 140 public short getShort() { 141 return buff.readShort(); 142 } 143 144 public int getInt() { 145 return buff.readInt(); 146 } 147 148 public long getLong() { 149 return buff.readLong(); 150 } 151 152 public double getDouble() { 153 return buff.readDouble(); 154 } 155 156 public byte[] gets(int len) { 157 byte[] data = new byte[len]; 158 buff.readBytes(data); 159 return data; 160 } 161 162 // 将data字节型数据转换为0~255 (0xFF 即BYTE)。 163 public short getUnsignedByte() { 164 return buff.readUnsignedByte(); 165 } 166 167 // 将data字节型数据转换为0~65535 (0xFFFF 即 WORD)。 168 public int getUnsignedShort() { 169 return buff.readUnsignedShort(); 170 } 171 172 public long getUnsignedInt() { 173 return buff.readUnsignedInt(); 174 } 175 176 public String getString() { 177 return buff.toString(Charset.forName("GBK")); 178 } 179 180 public String getString(int len) { 181 return buff.toString(0, len, Charset.forName("GBK")); 182 } 183 184 public byte[] array() { 185 int pos = buff.writerIndex(); 186 byte[] data = new byte[pos]; 187 buff.resetReaderIndex(); 188 buff.readBytes(data); 189 return data; 190 } 191 192 193 }
总结:对于NIO的ByteBuffer字节读写缓冲区操作,mina和netty都有封装,但是netty提供了更强大的封装和实现,更加方便我们操作字节缓冲区,推荐使用netty的ByteBuff!代码供大家对ByteBuff的封装参考~
文章封装的代码基于连接:
https://blog.csdn.net/alex_bean/article/details/51251015
https://blog.csdn.net/u010853261/article/details/53690780
https://www.cnblogs.com/zzt-lovelinlin/p/5292608.html
扫描二维码关注公众号,回复:
1579671 查看本文章