One. Java bytes
Byte is a basic data type in Java. A byte contains eight bits. The value of the byte ranges from -128 to +127.
Byte and other Java primitive types:
Two. Common packaging
For work reasons, I have encapsulated a library of operation bytes
Making address: https://github.com/fengzhizi715/bytekit
2.1 Features of ByteKit:
You can create Bytes in a variety of ways
Supports byte array and ByteBuffer operations
Immutable objects are supported: ByteArrayBytes and ByteBufferBytes
Support Transformer: built-in Copy, Contact, reverse, XOR, AND, OR, not, also support custom Transformer
Supports Hash: built-in MD5, SHA1, and SHA256
Conversion to hexadecimal strings is supported
Support mMAP common read and write operations: ReadByte /writeByte, readBytes/writeBytes, readInt/writeInt, readLong/writeLong, readDouble/writeDouble, readObject/writeObjec t
Supports object serialization, deserialization, and deep copy
Do not rely on any third party libraries
Bytes is an interface that has three implementation classes: ByteArrayBytes, ByteBufferBytes, and MmapBytes. The first two implementation classes are Immutable.
2.2 Immutable objects are supported
An Immutable object means that once an object is created, its state (the object’s data, the value of its attributes) cannot be changed.
Its advantages:
It’s simple to build, test, and use
Thread safety
No protective copy is required when used as a class property
Works well as Map keys and Set elements
2.3 Support Hash encryption
Encrypts byte[] in Bytes. In the Bytes interface, include the following default functions:
/ * *
* Use MD5 encryption
* @return
* /
default Bytes md5() {
return transform(new MessageDigestTransformer(MD5));
}
/ * *
* Use SHA1 encryption
* @return
* /
default Bytes sha1() {
return transform(new MessageDigestTransformer(SHA-1));
}
/ * *
* Use SHA256 encryption
* @return
* /
default Bytes sha256() {
return transform(new MessageDigestTransformer(SHA-256));
}
Unit testing:
@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 Serialization, deserialization, deep copy
Supports serialization, deserialization, and deep copy of objects. In the Bytes interface, include the following static functions:
/ * *
* Serialize an object, converting it to a byte array
* @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;
}
/ * *
* Deserialize byte numbers into objects
* @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;
}
/ * *
* Implement deep copies of objects by serializing/deserializing them
* @param obj
* @param
* @return
* /
staticT cloneObject(T obj) {
return (T) deserialize(serialize(obj));
}
Unit testing:
@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);
}
After testDeepCopy() is executed, u.name and newuser.name point to different memory addresses for different u and newUser addresses.
com.safframework.bytekit.domain.User@2b05039f
com.safframework.bytekit.domain.User@17d10166
2.5 Copy, Contact, reverse
Copy, contact and reverse are all Transformer methods. In the AbstractBytes class, include the following functions:
@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());
}
Unit testing:
@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 bit operation
Xor, AND, OR, and NOT are also available in Transformer. In the AbstractBytes class, include the following functions:
@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));
}
Unit testing:
@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 returns itself twice
}
2.7 Base64 encoding and decoding
@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 is converted to a byte array
@Test
public void testToByteArray() {
Bytes bytes = ByteBufferBytes.create(hello world).contact( tony.getBytes());
assertEquals(bytes.toString(), new String(bytes.toByteArray()));
}
3. Mmap operations
Mmap for Linux is a method of memory-mapping files.
Mmap maps a file or other object into memory. Files are mapped to multiple pages, and if the file size is not the sum of all pages, the unused space of the last page is cleared. Mmap is very useful in the user space mapping call system. The MMAP system call maps an open file to the user space of the process. The MMAP system call enables processes to share memory by mapping the same common file. After ordinary files are mapped to the address space of the process, the process can access the file just as it accesses ordinary memory without invoking operations such as read() and 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.14 d);
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.14 d, 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();
}
}
4. To summarize
Bytekit is a library of tools that manipulate bytes and does not rely on any third-party libraries. It encapsulates byte arrays, ByteBuffer operations, and supports read and write operations commonly used by Mmap.
Of course, it can also encapsulate a Protobuf ByteString or an Android Parcel, simply by implementing the Bytes interface.