如何在Java中从字节数组中删除前四个字节?

4

我有一个名为byteArr[]的字节数组。我需要从中删除前4个字节。我的代码如下所示。在这里,我使用字节数组来存储输入字符串。输出结果中有一些不必要的字节,即前四个字节不需要,从第五个字节开始是正确的。我的程序是使用RFID机器从相应的RFID标签中获取ID。

public class Serverc {

    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();

    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];

        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

    public static void connection() throws IOException {

        ServerSocket ss = new ServerSocket(9888);//exce
        ss.setSoTimeout(300000000);//exce
        System.out.println("Waiting for client on port " + ss.getLocalPort() + "...");

        while (true) {

            Socket server = ss.accept();//exce
            System.out.println("Just connected to " + server.getRemoteSocketAddress());

            int available = 0;
            DataInputStream in = new DataInputStream(server.getInputStream());//exce
            int input = 0;
            //BufferedReader br = new BufferedReader(in);
            byte byteArr[] = new byte[28];

            try {
                //read till the end of stream
                //while((input = in.available()) != -1)
                while ((input = in.read(byteArr)) != -1) {
                    System.out.println("Size read is " + input);
                    System.out.println("Data is " + bytesToHex(byteArr));
                }

                //System.out.println("inside finally");
                server.close();//exce
                //System.out.println("outside finally");
            } catch (SocketTimeoutException ex) {
                System.out.println("Socket timed out!");
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {

                e.printStackTrace();
            }
        }
    }

    public static void main(String args[]) throws IOException {
        Serverc obj = new Serverc();
        obj.connection();
    }
}

这是我的控制台。
Waiting for client on port 9888...
Just connected to /106.208.71.50:61532
Size read is 28
Data is 55000016910001DB00FB63ABEEAFC1EC888F10263410050711148F3500000000
Size read is 28
Data is 55000016910001DB00FB63ABEEAFC1EC888F10263410050711148F3500000000
Size read is 28
Data is 55000016910001DB00FB63ABEEAFC1EC888F10263410050711148F3500000000
Size read is 28
Data is 55000016910001DB00FB63ABEEAFC1EC888F10263410050711148F3500000000
Size read is 28
Data is 55000016910001DB00FB63ABEEAFC1EC888F10263410050711148F3500000000

我需要将结果中的55000016删除。

提前感谢。


如果你的数组不是非常庞大,只需将其转换为列表,然后逐个删除元素(列表会自动调整数组)。 - Juan Antonio Gomez Moriano
根据读取标签的情况,我的数组可能会变得非常庞大。因为在我的应用程序中需要读取很多标签。 - Miller
4个回答

9

您可以使用Arrays.copyOfRange方法来过滤掉不需要的字节,并将结果保存到一个新的字节数组中。

byte[] filteredByteArray = Arrays.copyOfRange(byteArr, 4, byteArr.length);

8
实际上这段代码存在一个错误。应该是byte[] filteredByteArray = Arrays.copyOfRange(byteArr, 4, byteArr.length); - morpheus

3
如果您想跳过前四个字节,请更改此处。
for (int j = 0; j < bytes.length; j++) {

转换为类似于

for (int j = 4; j < bytes.length; j++) {

或者你可以使用String.substring(int)

 bytesToHex(byteArr).substring(8); // <-- skip the first 4 bytes

0
最好跳过这4个字节。但是如果你想要移除它们,你应该使用这个解决方案(你的数组可能会变得非常大)。这个算法是你在Java中能够得到的最好的解决方案。空间复杂度O(1),时间复杂度O(n)。
void removeFourBytes(byte[] a) {
  for (int i = 4; i < a.length; i++) {
    a[i-4]=a[i];
  }
  for (int i = a.length - 1; i > a.length - 5; i--) {
    a[i] = 0;
  }
}

第二好的选择是System.arrayCopy() - O(n)空间,O(n)时间。


你不能将字节数组的成员设置为 null;在那一行上,你会得到一个编译器错误。 - Jules

0

你面临的问题比跳过每个数据包开头的4个字节更大。你的代码是这样的:

       byte byteArr[] = new byte[28];

        try {
            while ((input = in.read(byteArr)) != -1) {
                System.out.println("Size read is " + input);
                System.out.println("Data is " + bytesToHex(byteArr));
            }

请注意,您无法保证每次调用in.read()时都会读取所有28个字节,但是您的bytesToHex()方法假定数组中存在28个有效字节。您需要收集读入数组的数据,直到您拥有完整的数据包才能处理它,可能使用DataInputStream和方法readFully(byte[])。然后,您可以像其他答案建议的那样跳过前4个字节。


是的,没错,但是in.readFully(byteArr)会导致类型不匹配错误:无法从void转换为int。 - Miller
这是因为readFully总是要么填充字节数组(读取所有28个字节),要么抛出EOFException异常。 - Jules
你能给一个示例代码吗? - Miller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接