内容简介:byte (字节) 是 Java 中的基本数据类型,一个 byte 包含8个 bit(位),byte 的取值范围是-128到+127。byte 跟 Java 其他基本类型的关系:由于工作关系,我封装了一个操作字节的库
一. Java 的字节
byte (字节) 是 Java 中的基本数据类型,一个 byte 包含8个 bit(位),byte 的取值范围是-128到+127。
byte 跟 Java 其他基本类型的关系:
基本类型 | 所占字节数 | 备注 |
---|---|---|
byte | 1 | |
short | 2 | |
int | 4 | |
long | 8 | |
char | 2 | |
float | 4 | |
double | 8 | |
boolean | 1、4 | 《Java虚拟机规范》给出了4个字节,和boolean数组1个字节的定义,具体还要看虚拟机实现是否按照规范来 |
二. 常用封装
由于工作关系,我封装了一个操作字节的库
github 地址: github.com/fengzhizi71…
2.1 bytekit 的特点:
- 支持多种方式创建 Bytes
- 支持字节数组、ByteBuffer 的操作
- 支持 Immutable 对象:ByteArrayBytes、ByteBufferBytes
- 支持 Transformer: 内置 copy、contact、reverse、xor、and、or、not,也支持自定义 Transformer
- 支持 Hash: 内置 md5、sha1、sha256
- 支持转换成16进制字符串
- 支持 mmap 常用读写操作:readByte/writeByte、readBytes/writeBytes、readInt/writeInt、readLong/writeLong、readDouble/writeDouble、readObject/writeObject
- 支持对象的序列化、反序列化、深拷贝
- 不依赖任何第三方库
Bytes 是一个接口,它有三个实现类:ByteArrayBytes、ByteBufferBytes、MmapBytes。其中,前面两个实现类是 Immutable 对象。
2.2 支持 Immutable 对象
Immutable 对象(不可变对象),即对象一旦被创建它的状态(对象的数据,也即对象属性值)就不能改变。
它的优点:
- 构造、测试和使用都很简单
- 线程安全
- 当用作类的属性时不需要保护性拷贝
- 可以很好的用作Map键值和Set元素
2.3 支持 Hash 加密
对 Bytes 中的 byte[] 进行加密。在 Bytes 接口中,包含下面的默认函数:
/** * 使用md5加密 * @return */ default Bytes md5() { return transform(new MessageDigestTransformer("MD5")); } /** * 使用sha1加密 * @return */ default Bytes sha1() { return transform(new MessageDigestTransformer("SHA-1")); } /** * 使用sha256加密 * @return */ default Bytes sha256() { return transform(new MessageDigestTransformer("SHA-256")); } 复制代码
进行单元测试:
@Test public void testHash() { Bytes bytes = ByteArrayBytes.create("hello world"); assertEquals("5eb63bbbe01eeed093cb22bb8f5acdc3", bytes.md5().toHexString()); assertEquals("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed", bytes.sha1().toHexString()); assertEquals("b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9", bytes.sha256().toHexString()); } 复制代码
2.4 序列化、反序列化、深拷贝
支持对象的序列化、反序列化以及深拷贝。在 Bytes 接口中,包含下面的静态函数:
/** * 序列化对象,转换成字节数组 * @param obj * @return */ static byte[] serialize(Object obj) { byte[] result = null; ByteArrayOutputStream fos = null; try { fos = new ByteArrayOutputStream(); ObjectOutputStream o = new ObjectOutputStream(fos); o.writeObject(obj); result = fos.toByteArray(); } catch (IOException e) { System.err.println(e); } finally { IOUtils.closeQuietly(fos); } return result; } /** * 反序列化字节数字,转换成对象 * @param bytes * @return */ static Object deserialize(byte[] bytes) { InputStream fis = null; try { fis = new ByteArrayInputStream(bytes); ObjectInputStream o = new ObjectInputStream(fis); return o.readObject(); } catch (IOException e) { System.err.println(e); } catch (ClassNotFoundException e) { System.err.println(e); } finally { IOUtils.closeQuietly(fis); } return null; } /** * 通过序列化/反序列化实现对象的深拷贝 * @param obj * @param <T> * @return */ static <T> T cloneObject(T obj) { return (T) deserialize(serialize(obj)); } 复制代码
进行单元测试:
@Test public void testSerializeAndDeserialize() { User u = new User(); u.name = "tony"; u.password = "123456"; byte[] bytes = Bytes.serialize(u); User newUser = (User)Bytes.deserialize(bytes); assertEquals(u.name, newUser.name); assertEquals(u.password,newUser.password); } @Test public void testDeepCopy() { User u = new User(); u.name = "tony"; u.password = "123456"; User newUser = Bytes.cloneObject(u); System.out.println(u); System.out.println(newUser); assertNotSame(u,newUser); assertNotSame(u.name,newUser.name); } 复制代码
testDeepCopy() 执行后,u 和 newUser 地址的不同,u.name 和newUser.name 指向的内存地址也不同。
com.safframework.bytekit.domain.User@2b05039f com.safframework.bytekit.domain.User@17d10166 复制代码
2.5 copy、contact、reverse
copy、contact、reverse 都是采用 Transformer 的方式。在 AbstractBytes 类中,包含下面的函数:
@Override public Bytes copy() { return transform(new CopyTransformer(0, size())); } @Override public Bytes copy(int offset, int length) { return transform(new CopyTransformer(offset, length)); } @Override public Bytes contact(byte[] bytes) { return transform(new ConcatTransformer(bytes)); } @Override public Bytes reverse() { return transform(new ReverseTransformer()); } 复制代码
进行单元测试:
@Test public void testContact() { Bytes bytes = ByteBufferBytes.create("hello world").contact(" tony".getBytes()); assertEquals(bytes.toString(), "hello world tony"); } @Test public void testCopy() { Bytes bytes = ByteBufferBytes.create("hello world").contact(" tony".getBytes()); assertEquals(bytes.toString(), bytes.copy().toString()); } @Test public void testReverse() { Bytes bytes = ByteBufferBytes.create("hello world").contact(" tony".getBytes()); assertEquals(bytes.toString(), bytes.reverse().reverse().toString()); } 复制代码
2.6 位操作
xor、and、or、not 也是采用 Transformer 的方式。在 AbstractBytes 类中,包含下面的函数:
@Override public Bytes xor(byte[] bytes) { return transform(new BitWiseOperatorTransformer(bytes,BitWiseOperatorTransformer.Mode.XOR)); } @Override public Bytes and(byte[] bytes) { return transform(new BitWiseOperatorTransformer(bytes, BitWiseOperatorTransformer.Mode.AND)); } @Override public Bytes or(byte[] bytes) { return transform(new BitWiseOperatorTransformer(bytes, BitWiseOperatorTransformer.Mode.OR)); } @Override public Bytes not(byte[] bytes) { return transform(new BitWiseOperatorTransformer(bytes, BitWiseOperatorTransformer.Mode.NOT)); } 复制代码
进行单元测试:
@Test public void testBitWise() { ByteBufferBytes bytes = (ByteBufferBytes)ByteBufferBytes.create("hello world").contact(" tony".getBytes()); assertEquals(bytes.toString(), bytes.and(bytes.toByteArray()).or(bytes.toByteArray()).toString()); assertEquals(bytes.toString(), bytes.not(bytes.toByteArray()).not(bytes.toByteArray()).toString()); assertEquals(bytes.toString(), bytes.xor(bytes.toByteArray()).xor(bytes.toByteArray()).toString()); //两次xor 返回本身 } 复制代码
2.7 Base64 编码、解码
@Test public void testBase64() { ByteBufferBytes bytes = (ByteBufferBytes)ByteBufferBytes.create("hello world").contact(" tony".getBytes()); String base64 = new String(bytes.encodeBase64()); assertEquals(bytes.toString(), new String(Bytes.parseBase64(base64))); } 复制代码
2.8 Bytes 转换成字节数组
@Test public void testToByteArray() { Bytes bytes = ByteBufferBytes.create("hello world").contact(" tony".getBytes()); assertEquals(bytes.toString(), new String(bytes.toByteArray())); } 复制代码
三. mmap 的操作
Linux 的 mmap 是一种内存映射文件的方法。
mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。mmap在用户空间映射调用系统中作用很大。 mmap系统调用是将一个打开的文件映射到进程的用户空间,mmap系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read()、write()等操作。
import com.safframework.bytekit.domain.User; import com.safframework.bytekit.jdk.mmap.MmapBytes; import org.junit.After; import org.junit.Before; import org.junit.Test; import static junit.framework.TestCase.assertEquals; /** * Created by tony on 2018-12-24. */ public class MmapBytesTest { private MmapBytes mmapBytes; private String file; @Before public void setUp() { file = "test"; mmapBytes = new MmapBytes(file, (long) 1024 * 10); // 10M } @Test public void testWriteAndRead() throws Exception { mmapBytes.writeInt(12); mmapBytes.writeInt(34); mmapBytes.writeByte((byte) 5); mmapBytes.writeBytes(("this is tony").getBytes()); mmapBytes.writeLong(6666L); mmapBytes.writeDouble(3.14d); assertEquals(12, mmapBytes.readInt()); assertEquals(34, mmapBytes.readInt()); assertEquals((byte) 5, mmapBytes.readByte()); assertEquals("this is tony", new String(mmapBytes.readBytes(12))); assertEquals(6666L, mmapBytes.readLong()); assertEquals(3.14d, mmapBytes.readDouble()); } @Test public void testObject() throws Exception { User u = new User(); u.name = "tony"; u.password = "123456"; mmapBytes.writeObject(u); User temp = (User)mmapBytes.readObject(117); assertEquals(u.name, temp.name); assertEquals(u.password, temp.password); } @Test public void testFree() throws Exception { mmapBytes.writeInt(12); mmapBytes.writeInt(34); mmapBytes.writeByte((byte) 5); mmapBytes.free(); mmapBytes = new MmapBytes(file, (long) 1024 * 10); // 10M mmapBytes.writeInt(67); assertEquals(67, mmapBytes.readInt()); } @After public void tearDown() { mmapBytes.free(); } } 复制代码
四. 总结
bytekit 是一个操作字节的 工具 库,不依赖任何第三方库。它封装了字节数组、ByteBuffer 的操作,支持 mmap 常用的读写。
当然,它还可以封装 protobuf 的 ByteString 或者 Android 中的 Parcel,只需实现 Bytes 接口即可。
参考资料:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Designing for Emotion
Aarron Walter / Happy Cog / 2011-10-18 / USD 18.00
Make your users fall in love with your site via the precepts packed into this brief, charming book by MailChimp user experience design lead Aarron Walter. From classic psychology to case studies, high......一起来看看 《Designing for Emotion》 这本书的介绍吧!