android - 如何从字节数组中逐字节获取

标签 android string split byte

我从服务器以字符串格式收到响应,如

V1YYZZ0x0000010x0D0x00112050x0C152031962061900x0D410240x0E152031962061900x0F410240x1021TATADOCOMOINTERNET101

然后我将它转换为字节数组,因为我需要逐字节地从这个字节中获取值。

我试过

Arrays.copyOfRange(original,
                        from , to);

但它基于索引而不是基于字节。

我也尝试了以下解决方案,但它也会根据长度截断字符串(如果我使用字符串而不是字节[])。

public static String truncateWhenUTF8(String s, int maxBytes) {
    int b = 0;
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);

        // ranges from http://en.wikipedia.org/wiki/UTF-8
        int skip = 0;
        int more;
        if (c <= 0x007f) {
            more = 1;
        } else if (c <= 0x07FF) {
            more = 2;
        } else if (c <= 0xd7ff) {
            more = 3;
        } else if (c <= 0xDFFF) {
            // surrogate area, consume next char as well
            more = 4;
            skip = 1;
        } else {
            more = 3;
        }

        if (b + more > maxBytes) {
            return s.substring(0, i);
        }
        b += more;
        i += skip;
    }
    return s;
}

我知道如何计算字节长度的字符串,但它只给出完整的字节长度字符串

下面是我需要如何按字节提取数据包。

enter image description here

以上代码和参数仅为示例。我需要从字符串/字节数组中逐字节获取。

我搜索了很多但没有找到任何我可以引用的解决方案或链接。我不知道如何使用字节长度拆分字符串,因为我知道每个参数和值的字节长度。

请给我任何引用或提示。

最佳答案

确定什么等于字符串中的一个字节并非易事。您的字符串包含十六进制文本形式的字节:0x0D(一个字节,等于 13),但也包含作为子字符串的值。例如 1024 可以解释为一个整数,在本例中为 2 个字节,但也可以解释为由 4 个字符组成的文本,总计 8 个字节。

无论如何,我会使用正则表达式拆分字符串,然后将这些部分进一步拆分为长度和值:

String message = "V1YYZZ0x0000010x0D0x00112050x0C152031962061900x0D41024"+
    "0x0E152031962061900x0F410240x1021TATADOCOMOINTERNET101";
String regex = "(0)(x)(\\w\\w)";
String[] parts = message.split(regex);
Log.d(TAG,"HEADER = "+parts[0]);
for (int i=1; i<parts.length; i++) {
    String s = parts[i];
    // Only process if it has length > 0
    if (s.length()>0) {
        String len = "", val = "";
        // String s is now in format LVVVV where L is the length, V is the value
        if (s.length() < 11) {
            // 1 character indicates length, up to 9 contains value
            len = s.substring(0, 1);
            val = s.substring(1);
        } else if (s.length() > 10) {
            // 2 characters indicate length, up to 99 contains value
            len = s.substring(0, 2);
            val = s.substring(2);
        } else if (s.length() > 101) {
            // 3 characters indicate length, up to 999 contains value
            len = s.substring(0, 3);
            val = s.substring(3);
        }
        Log.d(TAG, "Length: " + len + " Value: " + val);
    }
}

这会产生以下输出:

D/Activity: HEADER = V1YYZZ
D/Activity: Length: 0 Value: 001
D/Activity: Length: 1 Value: 1205
D/Activity: Length: 15 Value: 203196206190
D/Activity: Length: 4 Value: 1024
D/Activity: Length: 15 Value: 203196206190
D/Activity: Length: 4 Value: 1024
D/Activity: Length: 21 Value: TATADOCOMOINTERNET101

然后您可以检查包(不需要头中的前两个包),将字符串转换为您想要的任何内容(例如 Integer.parseInt(val))

如果您解释 header 的结构 (V1YYZZ0x0000010x0D0x0011205),我可以改进我的答案以找到消息计数。

关于android - 如何从字节数组中逐字节获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25804166/

相关文章:

android - 插入到android sqlite数据库中的特定行

c++ - 无限循环搜索 C++ std::map

java - 从 PHP 到 Android 的 HTTP 响应字符串

split - 如何拆分 CSV 或 JSON 文件以实现最佳 Snowflake 摄取?

reactjs - 在 React Native 中渲染逗号分隔的值字符串

Android Studio Build of App 失败,声称 Keystore 被篡改

android - 如何在 Android 中编辑时在编辑文本中显示清除按钮

java - 显示自 Android 中某个日期以来过去的天数、小时数(天文台计时表)

c++ - 使用迭代器 C++ 删除 vector 中的重叠字符串

r - 选择数据框中向量的第一个元素以外的所有元素