如何解析数据/字节数组?

时间:2013-01-30 16:19:07

标签: java android parsing

我正在使用终端仿真器库来创建终端,然后我用它将通过串口输入的数据发送到串行设备。不是我有那个工作我想在屏幕上创建一些其他图形界面,可能只是一个textBox,它显示了用户的结果的简短版本以及终端中的完整版本。他们只需浏览一下即可快速查看结果。我想知道如何最好地解析它。当我发送一个命令时,一个字节数组被发回给我,包含这样的数据作为一组结果的例子:

Interface           IP-Address       Status                Protocol        
vlan1               192.168.1.1      up                    up  
Fa0/1i              unassigned       administratively down down
Fa0/1o              unassigned       down                  down
Fa1/0               unassigned       down                  down
Fa1/1               unassigned       down                  down
Fa1/2               unassigned       down                  down
Fa1/3               unassigned       down                  down
Fa1/4               unassigned       down                  down
Fa1/5               unassigned       down                  down
Fa1/6               unassigned       down                  down
Fa1/7               unassigned       down                  down
Fa1/8               unassigned       up                    up  
Fa1/9               unassigned       down                  down
Fa1/10              unassigned       up                    up  
Fa1/11              unassigned       down                  down
Gi0                 unassigned       up                    up  
switch# 

我该如何解析这个?我想要的是“接口vlan1的IP为192.1.1.168”或“接口Fa1 / 8接收到未分配的IP地址”。为用户显示,只列出最相关的数据。我会说些什么:

    if (dataReceived.charAt(i) == 'v'
    && dataReceived.charAt(i + 1) == 'l'
    && dataReceived.charAt(i + 2) == 'a'
    && dataReceived.charAt(i + 3) == 'n')
    && dataReceived.charAt(i + 4) == '1')
    && etc //check i is in bounds, check is the next non-whitespace character a number or a u somehow and so on 
        {
         //do things here
         //print out "The interface vlan1 is up with an IP of 192.1.1.168"
        }

这种方式看起来相当繁琐,检查每个字节,查看下一个字节是什么等等。这是最好/最正确的方式吗?

编辑:这是我目前的样本,我正在接收数据,我正在测试某些数据:

public void onDataReceived(int id, byte[] data) {


            dataReceived = new String(data);


        try {
            dataReceivedByte = dataReceived.getBytes("ASCII");
        } catch (UnsupportedEncodingException e) {
            Log.d(TAG, "exception");
            e.printStackTrace();
        }
        statusBool = true;
        Log.d(TAG, "in data received " + dataReceived);
        ((MyBAIsWrapper) bis).renew(data);


        runOnUiThread(new Runnable(){

            @Override
            public void run() {


            }});
        viewHandler.post(updateView);
    }


Handler viewHandler = new Handler();
    Runnable updateView = new Runnable() {
        @Override

        public void run() {

            mEmulatorView.invalidate();

            if (statusBool == true) {
                for (int i = 1; i < dataReceived.length() - 1; i++) {

                    if (dataReceived.charAt(i) == '>') {

                        Log.d(TAG, "found >");
                        deviceStatus = 0;
                    }
                    if (dataReceived.charAt(i) == '#'
                            && dataReceived.charAt(i - 1) != ')') {

                        Log.d(TAG, "found #");
                        deviceStatus = 1;
                    }
                    if ((i + 1) <= (dataReceived.length())
                            && dataReceived.charAt(i) == ')'
                            && dataReceived.charAt(i + 1) == '#') {

                        Log.d(TAG, "found config )#");
                        deviceStatus = 2;
                    }

                }
                statusBool = false;
                viewHandler.postDelayed(updateView, 1000);

            }
        }
    };

2 个答案:

答案 0 :(得分:1)

当您使用charAt()时,我认为dataReceivedString。如果没有,将数据转换为字符串可能会很方便,因为您可以使用方便的String方法。您可以使用String(byte[])构造函数将字节数组转换为字符串。

因此,您还可以使用contains()方法检查字符串是否包含特定的子字符串:

if(dataReceived.contains("vlan1")) {
  // do things here
}

或者,如果您对子字符串的位置感兴趣,可以使用indexOf()

答案 1 :(得分:1)

这将非常容易正确解析,但它在一个地方从结构良好的表降级为自由文本。下面的代码使用补丁替换;这不是很干净的解决方案。如果某些分隔符(如\ t)仅存在于列之间而不存在于列中的单词之间,则使用它会更好。解析固定宽度的部分是可能的,但也是一团糟。

假设输入是字符串x:

class Record {
  String mItf, mIp, mStatus, mProt;
}

ArrayList<Record> records = new ArrayList<Record>();

StringTokenizer st = new StringTokenizer(x,"\r\n"); 
  // Line by line but do not split at spaces.

st.nextToken(); // Discard the header line.

while (st.hasMoreTokens()) {
   String line = st.nextToken();

   // Group in a single word problematic two word cases (may be multiple):
   line = line.replace("administratively down","administratively_down");

   StringTokenizer sr = new StringTokenizer(line);
   if (sr.countTokens() >= 4) {
     Record r = new Record();
     r.mItf = sr.nextToken();
     r.mIp = sr.nexttoken();
     r.mStatus = sr.nextToken();
     r.mProt = sr.nextToken();
     records.add(r);
   }
}

之后,你可以做你喜欢的概括。