Java 如何解析数据/字节数组?
我使用终端仿真器库创建终端,然后使用它将通过串行输入的数据发送到串行设备。并不是说我在工作,我想创建一些其他的图形界面,也许只是一个文本框,在屏幕上为用户显示一个简短的结果版本以及终端中的完整版本。他们只需浏览一下,就可以更快地查看结果。我想知道如何最好地解析它。当我发送命令时,一个字节数组被发送回我,其中包含如下数据,作为一组结果的示例:Java 如何解析数据/字节数组?,java,android,parsing,Java,Android,Parsing,我使用终端仿真器库创建终端,然后使用它将通过串行输入的数据发送到串行设备。并不是说我在工作,我想创建一些其他的图形界面,也许只是一个文本框,在屏幕上为用户显示一个简短的结果版本以及终端中的完整版本。他们只需浏览一下,就可以更快地查看结果。我想知道如何最好地解析它。当我发送命令时,一个字节数组被发送回我,其中包含如下数据,作为一组结果的示例: Interface IP-Address Status Protocol vl
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);
}
}
};
public void onDataReceived(int-id,字节[]数据){
dataReceived=新字符串(数据);
试一试{
dataReceivedByte=dataReceived.getBytes(“ASCII”);
}捕获(不支持的编码异常e){
Log.d(标记为“例外”);
e、 printStackTrace();
}
statusBool=true;
Log.d(标签“接收到的数据中”+接收到的数据);
更新(数据);
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
}});
viewHandler.post(updateView);
}
Handler viewHandler=新处理程序();
Runnable updateView=new Runnable(){
@凌驾
公开募捐{
mEmulatorView.invalidate();
如果(statusBool==true){
for(int i=1;i'){
Log.d(标记“found>”);
deviceStatus=0;
}
if(dataReceived.charAt(i)='#'
&&dataReceived.charAt(i-1)!=')'){
Log.d(标记为“found#”);
deviceStatus=1;
}
如果在使用时((i+1),我假设dataReceived
是一个String
。如果不是,则可以方便地将数据转换为字符串,因为您可以使用方便的String
方法。您可以使用构造函数将字节数组转换为字符串
因此,您还可以使用该方法检查字符串是否包含特定的子字符串:
if(dataReceived.contains("vlan1")) {
// do things here
}
或者如果您对可以使用的子字符串的位置感兴趣。这很容易正确解析,但它会在一个位置从结构良好的表降级为自由文本。下面的代码使用修补替换;这不是一个非常干净的解决方案。如果像\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);
}
}
课堂记录{
字符串mItf、mIp、mStatus、mProt;
}
ArrayList记录=新的ArrayList();
StringTokenizer st=新的StringTokenizer(x,“\r\n”);
//逐行,但不要在空格处拆分。
st.nextToken();//放弃标题行。
而(st.hasMoreTokens()){
字符串行=st.nextToken();
//在一个单词中分组有问题的两个单词大小写(可以是多个):
行=行。替换(“管理性关闭”、“管理性关闭”);
StringTokenizer sr=新的StringTokenizer(行);
if(sr.countTokens()>=4){
记录r=新记录();
r、 mItf=sr.nextToken();
r、 mIp=sr.nexttoken();
r、 mStatus=sr.nextToken();
r、 mProt=sr.nextToken();
记录。添加(r);
}
}
在那之后,你可以做你喜欢的概括。你得到的是字节
还是字符
?我得到字节,但我只是把它转换成一个字符串来使用charAt dataReceived=新字符串(数据);是的,当使用这些方法时,我将字节数组转换为字符串。我看到.contains的问题是,如果一个字节数组带有vla,下一个字节数组带有n1,然后它们是两个单独的字符串等,那么会发生什么情况。因此,基本上需要缓冲传入的字节数组/块,直到有完整的行(例如,当收到换行符时)然后用这些字节数组创建字符串
。。是的,听起来不错。然后我可以使用contains,这样会更干净。