国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

實現(xiàn)對象轉(zhuǎn)成字節(jié)數(shù)組(整型支持按位寫入,字符串則按字節(jié)寫入)

這篇具有很好參考價值的文章主要介紹了實現(xiàn)對象轉(zhuǎn)成字節(jié)數(shù)組(整型支持按位寫入,字符串則按字節(jié)寫入)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

閑著無聊,寫了一個對象轉(zhuǎn)換成byte[]的工具類,支持整型按位寫入(大大節(jié)省空間),具體步驟如下:

1. 定義實體類和注解

public class User {

    /**
     * ID,4個字節(jié),32bit
     */
    @JSONField(ordinal = 1)
    @BitPos(offset=0,size = 32)
    public int id;

    /**
     * 姓名,10個字節(jié)(80bit)
     */
    @JSONField(ordinal = 2)
    @BitPos(offset = 32, size= 80)
    public String name;

    /**
     * 性別,0:男,1:女,1Bit
     */
    @JSONField(ordinal = 3)
    @BitPos(offset = 112, size = 1)
    public int sex;

    /**
     * 年齡,最大127,7Bit
     */
    @JSONField(ordinal = 4)
    @BitPos(offset = 113, size=7)
    public int age;

    /**
     * 身高,最大2^10-1=1023cm,10Bit
     */
    @JSONField(ordinal = 5)
    @BitPos(offset = 120, size = 10)
    public int height;

    /**
     * 體重,最大2^10-1=1023kg,10Bit
     */
    @JSONField(ordinal = 6)
    @BitPos(offset = 130, size = 10)
    public int weight;

    /**
     * 多少個月的薪水,最大2^4-1=15個月薪,4Bit
     */
    @JSONField(ordinal = 7)
    @BitPos(offset = 140, size=4)
    public int monthSalary;

    /**
     * 地址:20字節(jié),160bit
     */
    @JSONField(ordinal = 8)
    @BitPos(offset = 144, size = 160)
    public String address;


}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface BitPos {

    /**
     * 位置(占總長度的位置)
     */
    int offset() default  -1;

    /**
     * 長度(多少bit)
     */
    int size() default  -1;
}

2. 工具類

package com.hdwang.test.bit;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;

/**
 * 對象轉(zhuǎn)位字節(jié)(整型實現(xiàn)按bit寫入,字符串則按字節(jié)寫入)
 *
 * 時間: 2024/1/23 11:12
 */
public class ObjToBitBytesUtil {

    public static void main(String[] args) throws IllegalAccessException, UnsupportedEncodingException {
        User user = new User();
        user.id = 10001;
        user.name = "張三";
        user.sex = 0;
        user.age = 18;
        user.height = 170;
        user.weight = 50;
        user.monthSalary = 13;
        user.address = "浙江杭州西湖";

        System.out.println("原始對象:");
        System.out.println(JSON.toJSONString(user, SerializerFeature.WriteNullStringAsEmpty));

        //對象寫成字節(jié)數(shù)組
        byte[] bytes = writeObjToBitBytes(user, 38);
        System.out.println("對象的字節(jié)數(shù)組16進制表示:");
        printHex(bytes);


        //字節(jié)數(shù)組轉(zhuǎn)成對象
        User readUser = readBitBytesToObj(bytes);
        System.out.println("字節(jié)數(shù)組轉(zhuǎn)換成的對象:");
        System.out.println(JSON.toJSONString(readUser,SerializerFeature.WriteNullStringAsEmpty));
    }

    private static User readBitBytesToObj(byte[] bytes) throws IllegalAccessException, UnsupportedEncodingException {
        User user = new User();
        Field[] fields = user.getClass().getFields();
        for (Field field : fields) {
            BitPos bitPos = field.getAnnotation(BitPos.class);
            Object val = readField(bytes, field, bitPos.offset(), bitPos.size());
            field.set(user,val);
        }
        return user;
    }

    private static Object readField(byte[] buffer, Field field, int offset, int size) throws UnsupportedEncodingException {
        Object val = null;
       if(field.getType().equals(int.class) || field.getType().equals(Integer.class)){
           // 整型,按位讀取
           int valInt = 0;

           //起始緩存位置(第幾個字節(jié),從0開始)
           int startBufferIndex = offset / 8;
           //起始字節(jié)已經(jīng)占用了多少bit
           int startByteUsedBit = offset % 8;
           //起始字節(jié)需要讀取多少bit(默認剩余bit全部讀取)
           int startByteReadBit = 8 - startByteUsedBit;
           if(size < startByteReadBit){
               //需要讀取的bit數(shù)少,重置為實際需要讀取的bit數(shù)
               startByteReadBit = size;
           }
           //結(jié)束緩存位置(第幾個字節(jié))
           int endBufferIndex = (offset + size - 1) / 8;
           int endByteUseBit = ((offset + size - 1) % 8)+1;
           // 緩存間隔位置(緩存起止位置之間的間隔字節(jié)數(shù))
           int gapByteCount = endBufferIndex - startBufferIndex - 1;

           // 1. 讀取起始字節(jié)(讀高位)
           byte lowerByte = buffer[startBufferIndex];
           lowerByte = (byte) (lowerByte >>> startByteUsedBit);
           int mask = (1 << startByteReadBit) - 1;
           valInt = lowerByte & mask;

           // 2. 讀取中間字節(jié)(讀整個字節(jié))
           if(gapByteCount > 0) {
               for (int i = 0; i < gapByteCount; i++) {
                   int leftMove = startByteReadBit + (i * 8);
                   byte b = buffer[startBufferIndex+(i+1)];
                   valInt |= (b << leftMove);
               }
           }

           // 3. 讀取結(jié)束字節(jié)(讀取低位)
           if(endBufferIndex > startBufferIndex) {
               byte b = buffer[endBufferIndex];
               int leftMove = startByteReadBit + gapByteCount * 8;
               mask = (1 << endByteUseBit) - 1;
               valInt |= ((b & mask) << leftMove);
           }
           val = valInt;
       }else{
           // 字符串按字節(jié)讀取
           byte[] bytes = new byte[size/8];
           int startBufferIndex = offset / 8;
           for(int i=0;i< bytes.length;i++){
               bytes[i] = buffer[startBufferIndex++];
           }
           String valStr = new String(bytes,"utf-8");
           val = valStr;
       }
       return val;
    }

    private static byte[] writeObjToBitBytes(User user, int bufferSize) throws IllegalAccessException, UnsupportedEncodingException {
        byte[] buffer = new byte[bufferSize];
        Field[] fields = user.getClass().getFields();
        for (Field field : fields) {
            BitPos bitPos = field.getAnnotation(BitPos.class);
            Object val = field.get(user);
            writeField(buffer, val, bitPos.offset(), bitPos.size());
        }
        return buffer;
    }

    private static void writeField(byte[] buffer, Object val, int offset, int size) throws UnsupportedEncodingException {
        if (val instanceof Integer) {
            // 整型,按位寫入
            int valInt = (int) val;

            //起始緩存位置(第幾個字節(jié),從0開始)
            int startBufferIndex = offset / 8;
            //起始字節(jié)已經(jīng)占用了多少bit
            int startByteUsedBit = offset % 8;
            //起始字節(jié)需要寫入多少bit(默認剩余bit全部寫入)
            int startByteWriteBit = 8 - startByteUsedBit;
            if(size < startByteWriteBit){
                //需要寫入的bit數(shù)少,重置為實際需要寫入的bit數(shù)
                startByteWriteBit = size;
            }
            //結(jié)束緩存位置(第幾個字節(jié))
            int endBufferIndex = (offset + size - 1) / 8;
            int endByteUseBit = ((offset + size - 1) % 8)+1;
            // 緩存間隔位置(緩存起止位置之間的間隔字節(jié)數(shù))
            int gapByteCount = endBufferIndex - startBufferIndex - 1;

            // 1. 寫入起始字節(jié)(之前在低位可能已經(jīng)存在值了,現(xiàn)在寫入的寫到高位去)
            int mask = (1 << startByteWriteBit) - 1;
            //取低startByteWriteBit位,左移startByteUsedBit位,與原來的值或操作即可寫入高位
            buffer[startBufferIndex] |= ((valInt & mask) << startByteUsedBit);

            // 2. 寫中間字節(jié)(全字節(jié)寫入)
            if(gapByteCount > 0) {
                for (int i = 0; i < gapByteCount; i++) {
                    int rightMove = startByteWriteBit + (i * 8);
                    buffer[startBufferIndex+(i+1)] = (byte) ((valInt >> rightMove) & 0xFF);
                }
            }

            // 3. 寫結(jié)束字節(jié)(寫入低位即可)
            if(endBufferIndex > startBufferIndex) {
                int rightMove = startByteWriteBit + gapByteCount * 8;
                mask = (1 << endByteUseBit) - 1;
                buffer[endBufferIndex] = (byte) ((valInt >> rightMove) & mask);
            }
        } else {
            // 字符串直接按字節(jié)寫入
            byte[] bytes = val.toString().getBytes("utf-8");
            int actualByteCount = bytes.length;
            int startBufferIndex = offset / 8;
            int endBufferIndex = startBufferIndex + size/8-1;
            int byteIndex = 0;
            for(int i = startBufferIndex; i<=endBufferIndex; i++) {
                if(byteIndex <= actualByteCount-1) {
                    buffer[i] = bytes[byteIndex++];
                }else{
                    //補空格
                    buffer[i] = ' ';
                }
            }
        }

    }


    private static void printHex(byte[] byteArray) {
        for (byte b : byteArray) {
            // 將每個字節(jié)轉(zhuǎn)換為16進制字符串
            String hex = String.format("%02X", b);
            System.out.print(hex + " ");
        }
        System.out.println();
    }
}

?

?

3. 測試結(jié)果

原始對象:
{"id":10001,"name":"張三","sex":0,"age":18,"height":170,"weight":50,"monthSalary":13,"address":"浙江杭州西湖"}
對象的字節(jié)數(shù)組16進制表示:
11 27 00 00 E5 BC A0 E4 B8 89 20 20 20 20 24 AA C8 D0 E6 B5 99 E6 B1 9F E6 9D AD E5 B7 9E E8 A5 BF E6 B9 96 20 20 
字節(jié)數(shù)組轉(zhuǎn)換成的對象:
{"id":10001,"name":"張三    ","sex":0,"age":18,"height":170,"weight":50,"monthSalary":13,"address":"浙江杭州西湖  "}

?

?

參考文章:

https://www.cnblogs.com/Dotnet9-com/p/17981055文章來源地址http://www.zghlxwxcb.cn/news/detail-818966.html

到了這里,關(guān)于實現(xiàn)對象轉(zhuǎn)成字節(jié)數(shù)組(整型支持按位寫入,字符串則按字節(jié)寫入)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包