0

ターミナルエミュレータライブラリを使用してターミナルを作成し、それを使用してシリアル経由で入力されたデータをシリアルデバイスに送信します。端末の完全なバージョンと一緒に、ユーザーの結果のより簡単なバージョンを表示する画面上に、おそらくテキストボックスだけのような他のグラフィカルインターフェイスを作成したいと思っているわけではありません。これを一目見るだけで、結果をすばやく確認できます。私はそれを最もよく解析する方法を考えています。コマンドを送信すると、結果の 1 つのセットの例として、次のようなデータを含むバイト配列が返されます。

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 は 192.1.1.168 の IP で稼働しています」または「インターフェイス 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);

            }
        }
    };
4

2 に答える 2

1

を使用しているcharAt()ので、それdataReceivedString. そうでない場合は、便利Stringなメソッドを利用できるため、データを文字列に変換すると便利な場合があります。コンストラクターを使用して、バイト配列を文字列に変換できますString(byte[])

したがって、contains()メソッドを使用して、文字列に特定の部分文字列が含まれているかどうかを確認することもできます。

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

または、使用できる部分文字列の場所に興味がある場合は、indexOf().

于 2013-01-30T16:23:48.287 に答える
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);
   }
}

その後、好きな一般化を行うことができます。

于 2013-01-30T16:38:26.457 に答える