【问题标题】:How to remove first 4 bytes from a byte array in Java? [duplicate]如何从Java中的字节数组中删除前4个字节? [复制]
【发布时间】:2015-01-11 10:56:29
【问题描述】:

我有一个名为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。 提前谢谢

【问题讨论】:

  • 如果你的数组不是海量的,只要把它转换成一个列表,然后一个一个地删除元素(列表会移动数组)
  • 基于读取标签,我的数组可能会变得庞大。因为在我的应用程序中需要读取很多标签

标签: java arrays bytearray datainputstream


【解决方案1】:

如果你想跳过前四个字节改变这个,

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

【讨论】:

    【解决方案2】:

    最好跳过这 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;你会在该行得到一个编译器错误。
    【解决方案3】:

    除了在每个数据包的开头跳过 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 个有效字节。在处理之前,您需要收集读入数组的数据,直到获得所有数据包,可能使用DataInputStreamreadFully(byte[]) 方法。 然后您可以按照其他答案中的建议跳过前 4 个字节。

    【讨论】:

    • :-是的,但 in.readFully(byteArr) 将导致类型不匹配错误:无法从 void 转换为 int
    • 这是因为 readFully 总是要么填充字节数组(读取所有 28 个字节)要么抛出 EOFException。
    • 你能给个示例代码吗
    【解决方案4】:

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

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

    【讨论】:

    • 这段代码实际上有一个错误。应该是 byte[] filteredByteArray = Arrays.copyOfRange(byteArr, 4, byteArr.length);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    • 2012-12-28
    • 2011-09-16
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    相关资源
    最近更新 更多