iT邦幫忙

0

一筆資料在autoboxing (byte array to list)後, 再 unboxing( list to byte array) ,資料值會改變

今日調整boxing unboxing程式邏輯, 發現一個問題 ,我將byte array的資料做autoboxing轉乘list後, 再從list unboxing轉回byte array,資料值會改變 ,目前查不出的問題, 所以上來發問, 請各位大神解惑

以下為主程式源碼:

            byte[] temp = characteristic.getValue();

            byte[] increaseCapacity = new byte[temp.length];

            System.arraycopy(temp, 0, increaseCapacity, 0, temp.length);

            Byte[] byteObjects = new Byte[increaseCapacity.length];

            int i = 0;

            for (byte b : increaseCapacity) {
                byteObjects[i++] = b;  // Autoboxing.....
            }
            
            rawDataList.addAll(Arrays.asList(byteObjects));

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = null;

            try {
                oos = new ObjectOutputStream(baos);
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                oos.writeObject(rawDataList);
            } catch (IOException e) {
                e.printStackTrace();
            }

            byte[] byteArray = baos.toByteArray();

            int j=0;
            byte[] bytes = new byte[byteArray.length];
            for(Byte b: byteArray)
                bytes[j++] = b.byteValue();

            size = bytes.length;

            for (int m = 0; m < size; m++) {
                if (m + 1 < size && m + 2 < size && m + 3 < size) {
                    if ((bytes[m] & 0xFF) == 2 && (bytes[m+1] & 0xFF) == 1 && (bytes[m+2] & 0xFF) == 4 && (bytes[m+3] & 0xFF) == 3) {
                        len = (bytes[m+8] & 0xFF);
                        len2 = (bytes[m+9] & 0xFF);
                        len3 = (bytes[m+10] & 0xFF);
                        len4 = (bytes[m+11] & 0xFF);

                        dataLen = len + len2 + len3 + len4 - 4;

                        if (m+dataLen+12 < size && m+dataLen+13 < size && m+dataLen+14 < size && m+dataLen+15 < size) {
                            if (bytes[m+dataLen+12] == -1 && bytes[m+dataLen+13] == -1 && bytes[m+dataLen+14] == -1 && bytes[m+dataLen+15] == -1)
                            {
                                findHeadTail(bytes);
                            }
                        }
                    }
                }
            }

方法程式碼:

public void findHeadTail(byte[] array) {
            byte[] testBytes = new byte[array.length];

            int length = 0;
            int length2 = 0;
            int length3 = 0;
            int length4 = 0;
            int dataLength = 0;
            int size = array.length;

            for (int k = 0; k < size; k++) {
                if (k + 1 < size && k + 2 < size && k + 3 < size) {
                    if ((array[k] & 0xFF) == 2 && (array[k+1] & 0xFF) == 1 && (array[k+2] & 0xFF) == 4 && (array[k+3] & 0xFF) == 3) {
                        length = (array[k+8] & 0xFF);
                        length2 = (array[k+9] & 0xFF);
                        length3 = (array[k+10] & 0xFF);
                        length4 = (array[k+11] & 0xFF);

                        dataLength = length + length2 + length3 + length4 - 4;

                        if (k+dataLength+12 < size && k+dataLength+13 < size && k+dataLength+14 < size && k+dataLength+15 < size) {
                            if (array[k+dataLength+12] == -1 && array[k+dataLength+13] == -1 && array[k+dataLength+14] == -1 && array[k+dataLength+15] == -1)
                            {
                                for (int p=k+12; p<k+12+dataLength; p++){
                                    testBytes[p] = array[p];
                                }

                                StringBuilder stringBuilder = new StringBuilder(testBytes.length);
                                for (byte byteChar : testBytes)
                                    stringBuilder.append(String.format("%02X ", byteChar));
                                System.out.println(stringBuilder.toString());

                            }
                        }
                    }
                }
            }

        }

autoboxing前的原始資料:
https://ithelp.ithome.com.tw/upload/images/20211116/20143658wSsAVQU1qt.png

autoboxing後:
https://ithelp.ithome.com.tw/upload/images/20211116/20143658YYMqKUTutg.png

做完unboxing後:
https://ithelp.ithome.com.tw/upload/images/20211116/20143658DLdyoYTzcV.png

1 個回答

1
海綿寶寶
iT邦大神 1 級 ‧ 2021-11-17 09:53:49
最佳解答

先說結論
byte[] byteArray = baos.toByteArray();之後資料就錯了
而且也不是 list 跟 bytearray 互轉的原因

我實在是看不懂為什麼要把同樣的資料轉來轉去
我只會用最笨的方法 debug

以下是測試結果及測試程式
https://ithelp.ithome.com.tw/upload/images/20211117/20001787DuFEX8ZNeq.png

import java.util.Arrays;
import java.util.ArrayList;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;

public class HelloWorld{

     public static void main(String []args){
        System.out.println("1.----------------------- origin byte[] temp");
        byte[] temp = new byte[] {2,1,4,3,1,0,0,0};
        System.out.println("Len="+temp.length + " " + Arrays.toString(temp));
        
        System.out.println("2.----------------------- copy as byte[] increaseCapacity");
        byte[] increaseCapacity = new byte[temp.length];
        System.arraycopy(temp, 0, increaseCapacity, 0, temp.length);
        System.out.println("Len="+increaseCapacity.length + " " + Arrays.toString(increaseCapacity));
      
        System.out.println("3.----------------------- copy as Byte[] byteObjects ");      
        Byte[] byteObjects = new Byte[increaseCapacity.length];
        int i = 0;
        for (byte b : increaseCapacity) {
            byteObjects[i++] = b;  // Autoboxing.....
        }  
        System.out.println("Len="+byteObjects.length + " " + Arrays.toString(byteObjects));
        
        System.out.println("4.----------------------- add as  ArrayList<Byte> rawDataList  ");
        ArrayList<Byte> rawDataList = new ArrayList<>();
        rawDataList.addAll(Arrays.asList(byteObjects));
        System.out.print("Len="+rawDataList.size() + " ");
        for(i = 0; i < rawDataList.size(); i++) {   
             System.out.print(String.format("0x%02X ", rawDataList.get(i)));
        }  
        System.out.println();
        
        System.out.println("5.----------------------- copy as byte[] bytes via ByteArrayOutputStream  ");        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = null;

        try {
            oos = new ObjectOutputStream(baos);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            oos.writeObject(rawDataList);
        } catch (IOException e) {
            e.printStackTrace();
        }

        byte[] byteArray = baos.toByteArray();
        System.out.println("Len="+byteArray.length + " " + Arrays.toString(byteArray));        
     }
}
habb2930 iT邦新手 5 級 ‧ 2021-11-17 10:17:45 檢舉

大神的意思我大約明白了, 資料轉來轉去是因為我沒法使用array 做封包資料串接, 只好用arraylist做 ,再轉回來 , 為了處理資料型態不同問題, 感謝大神

我要發表回答

立即登入回答