【问题标题】:How to deal with huge amount of byte arrays如何处理大量字节数组
【发布时间】:2023-03-24 05:53:01
【问题描述】:

所以我从 USB 设备接收字节数组(一些日志消息)并且我遇到了一个问题,我不知道解析或读取它们的最佳方法是什么...

这就是接收者:

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);
        }

....

所以我在这里面临的问题是,如何将所有这些字节数组组合成一个!然后在那个大数组上做 printHex..

【问题讨论】:

  • 虽然我不能给你一个详细的答案,但我建议你看看 RxJava,尤其是 Flowables、Backpressure 和 Buffer。 reactivex.io/intro.html
  • 谢谢我的朋友,但我没有时间去实现它:)
  • 所以,也许我的理解不正确:您要做的是在您的处理程序中处理 List 并将其转换为 List ,其中每个字符串都是printToHex(字节)的结果?如果是这样的话,我现在就发布一个简单的答案
  • 问题是:我正在接收字节数组,我立即通过 pritHex 方法对其进行格式化,我认为这会导致一些延迟并且我会丢失一些字节,从而导致消息无法读取......所以我想要,而不是立即将其格式化为十六进制,将所有这些字节数组添加到某些东西(字节数组列表)中,然后组合成一比一的大字节数组(可能很大!)。然后遍历那个大数组并进行格式化...到那时,接收器将停止,希望不会丢失任何字节...
  • 是的,我理解了大意,但我不知道您是否需要所有这些方面的帮助,或者只是最后的字节格式

标签: java android arrays byte android-handler


【解决方案1】:

您的 printToHex 函数应如下所示,传递读取的字节数。我从另一个帖子中复制了一些代码。

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); 
}

【讨论】:

  • 仍然感觉我丢失了一些消息:/ 我不知道缓冲区大小是否有问题,或者批量传输超时。我知道我应该收到更多的特定消息,但我只收到一个
  • @joe 使用 logCat 打印调用 printHex 和不调用得到多少字节,并进行比较。
  • 这样记录很难,因为我不知道我应该收到多少条消息...我知道我应该寻找应该发生的特定消息,实际上更多相同的消息应该在我发送特定的 AT 命令后收到...我看到一条消息或有时没有..但我应该收到更多...所以这只能意味着其中一些“丢失”
【解决方案2】:

好的,这里有两种方法可以在最后处理最终的字节数组列表,这取决于你想要什么。

备选方案 1:收集到字符串列表

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 字节,那么您应该没有任何问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多