gpt4 book ai didi

java - 在Java协议(protocol)层提取数据最不痛苦的方法是什么?

转载 作者:太空宇宙 更新时间:2023-11-04 07:43:06 26 4
gpt4 key购买 nike

我正在尝试实现一个 Android 应用程序来连接到开源软件 Motion。目标是能够检查应用程序的状态并获取最后捕获的图​​像。

我不太用 Java 编程,我的背景主要是 C 和 Python。我在理解 Android 的 UI 部分方面没有遇到任何真正的问题,但我发现使用任何类型的字节缓冲区都非常痛苦。 Motion 软件有一个非常简单的 HTTP API。在 Java 中打开 URL 连接很容易。默认页面的响应如下所示

Motion 3.2.12 Running [4] Threads
0
1
2
3

就我的目的而言,应用程序需要做的第一件事是解析线程数。在某些时候,我还可以从第一行检索版本号,但这目前并不重要。

这是我的代码

package com.hydrogen18.motionsurveillanceviewer;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import java.util.List;

public class MotionHttpApi {
String host;
int port = 80;
boolean secure = false;

int numberOfThreads = -1;

String getBaseUrl()
{
StringBuilder sb = new StringBuilder();

sb.append(secure ? "https://" : "http://");
sb.append(host);
sb.append(':');
sb.append(port);

return sb.toString();
}

public int getNumberOfCameras() throws IOException
{
if(numberOfThreads == -1)
{
retrieveSplash();
}

if(numberOfThreads == 1)
{
return 1;
}
return numberOfThreads - 1;
}
void retrieveSplash () throws IOException
{
URL url = new URL(getBaseUrl());

HttpURLConnection conn = (HttpURLConnection)url.openConnection();

if(conn.getResponseCode()!=HttpURLConnection.HTTP_OK)
{
throw new IOException("Got response code" + conn.getResponseCode());
}

try{
Byte[] buffer = new Byte[512];
byte[] sbuf = new byte[128];
int offset = 0;
InputStream in = new BufferedInputStream(conn.getInputStream());

boolean foundInfoString= false;
while( ! foundInfoString)
{
//Check to make sure we have not run out of space
if(offset == buffer.length)
{
throw new IOException("Response too large");
}

//Read into the smaller buffer since InputStream
//can't write to a Byte[]
final int result = in.read(sbuf,0,sbuf.length);

//Copy the data into the larger buffer
for(int i = 0; i < result;++i)
{
buffer[offset+i] = sbuf[i];
}
//Add to the offset
offset+=result;

//Wrap the array as a list
List<Byte> list = java.util.Arrays.asList(buffer);

//Find newline character
final int index = list.indexOf((byte) '\n');

//If the newline is present, extract the number of threads
if (index != -1)
{
//Find the number of threads
//Thread number is in the first lin like "[X]"
final int start = list.indexOf((byte)'[');
final int end = list.indexOf((byte)']');

//Sanity check the bounds
if(! (end > start))
{
throw new IOException("Couldn't locate number of threads");
}

//Create a string from the Byte[] array subset
StringBuilder sb = new StringBuilder();
for(int i = start+1; i != end; ++i)
{
final char c = (char) buffer[i].byteValue();
sb.append(c);
}
String numThreadsStr = sb.toString();

//Try and parse the string into a number
try
{
this.numberOfThreads = Integer.valueOf(numThreadsStr);
}catch(NumberFormatException e)
{
throw new IOException("Number of threads is NaN",e);
}

//No more values to extract
foundInfoString = true;
}

//If the InputStream got EOF and the into string has not been found
//Then an error has occurred.
if(result == -1 && ! foundInfoString )
{
throw new IOException("Never got info string");
}
}

}finally
{
//Close the connection
conn.disconnect();
}

}

public MotionHttpApi(String host,int port)
{
this.host = host;
this.port = port;
}
}

当您调用 getNumberOfCameras() 时,代码可以正常工作。但我想我一定还没有真正理解java方面的东西,因为retrieveSplash方法太复杂了。我只需 10 行左右的 C 代码或 1 行 Python 代码就可以完成同样的事情。当然必须有一种更明智的方法来操作 java 中的字节吗?

我认为存在一些样式问题,例如每当整数无法解析时我可能不应该抛出 IOException 。但这是一个单独的问题。

最佳答案

按照 Gautam Tandon 的建议阅读第一行,然后使用正则表达式。然后您可以检查正则表达式是否匹配,甚至可以轻松提取数字。

正则表达式可以在 http://txt2re.com 创建。我已经为你做到了。该页面甚至创建 Java、Pyhton、C 等文件供您使用。

// URL that generated this code:
// http://txt2re.com/index-java.php3?s=Motion%203.2.12%20Running%20[4]%20Threads&-7&-19&-5&-20&-1&2&-22&-21&-62&-63&15

import java.util.regex.*;

class Main
{
public static void main(String[] args)
{
String txt="Motion 3.2.12 Running [4] Threads";

String re1="(Motion)"; // Word 1
String re2="( )"; // White Space 1
String re3="(3\\.2\\.12)"; // MMDDYY 1
String re4="( )"; // White Space 2
String re5="(Running)"; // Word 2
String re6="( )"; // White Space 3
String re7="(\\[)"; // Any Single Character 1
String re8="(\\d+)"; // Integer Number 1
String re9="(\\])"; // Any Single Character 2
String re10="( )"; // White Space 4
String re11="((?:[a-z][a-z]+))"; // Word 3

Pattern p = Pattern.compile(re1+re2+re3+re4+re5+re6+re7+re8+re9+re10+re11,Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher m = p.matcher(txt);
if (m.find())
{
String word1=m.group(1);
String ws1=m.group(2);
String mmddyy1=m.group(3);
String ws2=m.group(4);
String word2=m.group(5);
String ws3=m.group(6);
String c1=m.group(7);
String int1=m.group(8);
String c2=m.group(9);
String ws4=m.group(10);
String word3=m.group(11);
System.out.print("("+word1.toString()+")"+"("+ws1.toString()+")"+"("+mmddyy1.toString()+")"+"("+ws2.toString()+")"+"("+word2.toString()+")"+"("+ws3.toString()+")"+"("+c1.toString()+")"+"("+int1.toString()+")"+"("+c2.toString()+")"+"("+ws4.toString()+")"+"("+word3.toString()+")"+"\n");
}
}
}

//-----
// This code is for use with Sun's Java VM - see http://java.sun.com/ for downloads.
//
// Paste the code into a new java application or a file called 'Main.java'
//
// Compile and run in Unix using:
// # javac Main.java
// # java Main
//

String int1=m.group(8); 为您提供所需的整数。当然你可以简化上面的代码。现在太冗长了。

关于java - 在Java协议(protocol)层提取数据最不痛苦的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15733939/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com