代码之家  ›  专栏  ›  技术社区  ›  joe

如何处理大量字节数组

  •  0
  • joe  · 技术社区  · 6 年前

    这就是接收机:

    static class ReceiveLogsThread implements Runnable {
        private static final String TAG = "IoTReceiveLogsThread";
        Message msgRead;
    
        ReceiveLogsThread() {
        }
    
        public void run() {
            byte[] rbuf = new byte[4096];
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    int len = mSerial.readLog(rbuf, mSerialPortLog);
                    if (len > 0) {
                    //    Crashlytics.log(Log.DEBUG, TAG, "ReceiveLogsThread: " + printHex(rbuf));
                    //    this.msgRead = receiveLogsHandler.obtainMessage(HANDLE_READ, printHex(rbuf));
                        this.msgRead = receiveLogsHandler.obtainMessage(HANDLE_READ, rbuf);
                        receiveLogsHandler.sendMessage(this.msgRead);
                    }
                } catch (NullPointerException e1) {
                    e1.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            Thread.currentThread().interrupt();
            if (!mReadFlag) {
                Crashlytics.log(Log.WARN, TAG, "Receive thread finished");
            }
        }
    }
    

    正如您所看到的,printHex()方法被注释,因为我认为它导致了由于实时解析而丢失一些消息的问题,您可以从它的实现中看到

       private static String printHex(byte[] bytes) {
        Formatter formatter = new Formatter();
    
        for (byte b : bytes) {
            formatter.format("%02x", b);
        }
        String hex = formatter.toString();
        return hex;
    }
    

    我不认为在收到字节数组后立即使用printHex方法是个好主意,因为字节的速度太快了,所以我想尝试另一种方法。。

    我想将它们作为字节数组发送,然后在完成所有操作后解析它们,所以我不确定如何正确实现它。。。

    下面是我的活动中的一个接收处理程序,我将这些数组存储到字节数组列表中,其中可能包含30000个字节数组:

        private List<byte[]> logs = new ArrayList<>();
    
    Handler receiveLogsHandler = new Handler(Looper.getMainLooper()) {
        public void handleMessage(Message msgRW) {
            super.handleMessage(msgRW);
            //   logMessagesList.add(msgRW.obj.toString().toUpperCase());
            //      String message = msgRW.obj.toString().toUpperCase();
    
            if(shouldCollectLogs) {
                byte[] message = (byte[]) msgRW.obj;
                logs.add(message);
            }
    
    ....
    

    2 回复  |  直到 6 年前
        1
  •  0
  •   lionscribe    6 年前

    private final static char[] hexArray = "0123456789ABCDEF".toCharArray(); 
    public static String printToHex(byte[] bytes, int len) { 
        char[] hexChars = new char[len * 2]; 
        for ( int j = 0; j < len; j++ ) { 
            int v = bytes[j] & 0xFF; 
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 
        }
        return new String(hexChars); 
    }
    
        2
  •  0
  •   dglozano    6 年前

    好的,这里有两种方法来处理最后的字节数组列表,具体取决于您想要什么。

    List<String> hexStrings = listOfBytes.parallelStream() //Process in paralell each byte array
                .map(bytes -> printHex(bytes)) // Map each byte array from byte[] to String
                .collect(Collectors.toList());// Collect the streams into one final list
    

    备选方案2:收集到一个字符串

    String oneBigStringOfBytesInHex = listOfBytes.parallelStream() //Process in paralell each byte array
                    .map(bytes -> printHex(bytes)) // Map each byte array from byte[] to String
                    .collect(Collectors.joining()); // Concat the streams into one final String
    

    对于第二个备选方案,您应该小心,您必须考虑字符串的最大大小。 2147483647 (2^31 - 1) . 无论如何,如果您的最终数据量是一个30.000字节数组的列表,每个数组4096字节,那么您应该不会有任何问题。