Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,如何围绕字节序列拆分字节数组?_Java - Fatal编程技术网

在Java中,如何围绕字节序列拆分字节数组?

在Java中,如何围绕字节序列拆分字节数组?,java,Java,如何在Java中围绕字节序列拆分字节[]?类似于的字节[]版本 例子 让我们以这个字节数组为例: [11 11 FF 22 22 FF 33] 让我们选择分隔符 [FF FF] 然后拆分将导致以下三部分: [11] [22] [33] 编辑: 请注意,由于编码问题,您无法将字节[]转换为字符串,然后将其拆分,然后再返回。当您在字节数组上进行这种转换时,得到的byte[]将不同。请参阅: 请参阅 您可以从字节数组构造字符串对象。我想你知道其余的 public static byte[][] spl

如何在Java中围绕字节序列拆分
字节[]
?类似于的
字节[]
版本

例子 让我们以这个字节数组为例:
[11 11 FF 22 22 FF 33]

让我们选择分隔符
[FF FF]

然后拆分将导致以下三部分:
[11]

[22]

[33]

编辑: 请注意,由于编码问题,您无法将
字节[]
转换为
字符串
,然后将其拆分,然后再返回。当您在字节数组上进行这种转换时,得到的
byte[]
将不同。请参阅:

请参阅

您可以从
字节
数组构造
字符串
对象。我想你知道其余的

public static byte[][] splitByteArray(byte[] bytes, byte[] regex, Charset charset) {
    String str = new String(bytes, charset);
    String[] split = str.split(new String(regex, charset));
    byte[][] byteSplit = new byte[split.length][];
    for (int i = 0; i < split.length; i++) {
        byteSplit[i] = split[i].getBytes(charset);
    }
    return byteSplit;
}

public static void main(String[] args) {
    Charset charset = Charset.forName("UTF-8");
    byte[] bytes = {
        '1', '1', ' ', '1', '1',
        'F', 'F', ' ', 'F', 'F',
        '2', '2', ' ', '2', '2', ' ', '2', '2',
        'F', 'F', ' ', 'F', 'F',
        '3', '3', ' ', '3', '3', ' ', '3', '3', ' ', '3', '3'
    };
    byte[] regex = {'F', 'F', ' ', 'F', 'F'};
    byte[][] splitted = splitByteArray(bytes, regex, charset);
    for (byte[] arr : splitted) {
        System.out.print("[");
        for (byte b : arr) {
            System.out.print((char) b);
        }
        System.out.println("]");
    }
}
publicstaticbyte[]splitByteArray(byte[]bytes,byte[]regex,Charset字符集){
String str=新字符串(字节,字符集);
String[]split=str.split(新字符串(regex,charset));
byte[][]byteSplit=新字节[split.length][];
对于(int i=0;i
请注意,如果您使用编码“iso8859-1”,您可以通过字符到字节的一对一映射,可靠地从字节[]转换为字符串并返回

然而,这仍然是一个丑陋的解决方案

我想你需要自己动手

我建议分两个阶段解决:

  • 了解如何找到分隔符每次出现时的索引数量。谷歌为“Knuth Morris Pratt”提供了一个高效的算法——尽管对于短分隔符来说,更简单的算法也可以
  • 每次找到索引时,使用Arrays.copyOfRange()获取所需的片段并将其添加到输出列表中
  • 这里使用的是一种简单的模式查找算法。如果分隔符很长,KMP就值得了(因为它可以节省回溯,但如果分隔符嵌入的序列在末尾不匹配,就不会遗漏分隔符)

    publicstaticbooleanismatch(字节[]模式,字节[]输入,int-pos){
    for(int i=0;ifor(int i=0;i滚动您自己的是唯一的方法。如果您对非标准库开放,我可以提供的最佳想法是Apache提供的此类:

    Knuth的解决方案可能是最好的,但我会将数组视为堆栈,并执行以下操作:

    List<ArrayByteList> targetList = new ArrayList<ArrayByteList>();
    while(!stack.empty()){
      byte top = stack.pop();
      ArrayByteList tmp = new ArrayByteList();
    
      if( top == 0xff && stack.peek() == 0xff){
        stack.pop();
        continue;
      }else{
        while( top != 0xff ){
          tmp.add(stack.pop());
        }
        targetList.add(tmp);
      }
    }
    
    List targetList=new ArrayList();
    而(!stack.empty()){
    字节top=stack.pop();
    ArrayByteList tmp=新的ArrayByteList();
    if(top==0xff&&stack.peek()==0xff){
    stack.pop();
    继续;
    }否则{
    while(顶部!=0xff){
    添加(stack.pop());
    }
    targetList.add(tmp);
    }
    }
    

    我知道这是非常快速和肮脏的,但它应该在所有情况下提供O(n)。

    您可以使用它。

    这里是一个简单的解决方案

    与avgvstvs方法不同,它处理任意长度的分隔符。最上面的答案也不错,但作者尚未解决Eitan Perkal指出的问题。使用Perkal建议的方法可以避免这个问题

    public static List<byte[]> tokens(byte[] array, byte[] delimiter) {
            List<byte[]> byteArrays = new LinkedList<>();
            if (delimiter.length == 0) {
                return byteArrays;
            }
            int begin = 0;
    
            outer:
            for (int i = 0; i < array.length - delimiter.length + 1; i++) {
                for (int j = 0; j < delimiter.length; j++) {
                    if (array[i + j] != delimiter[j]) {
                        continue outer;
                    }
                }
                byteArrays.add(Arrays.copyOfRange(array, begin, i));
                begin = i + delimiter.length;
            }
            byteArrays.add(Arrays.copyOfRange(array, begin, array.length));
            return byteArrays;
        }
    
    公共静态列表令牌(字节[]数组,字节[]分隔符){
    List ByteArray=新建LinkedList();
    if(delimiter.length==0){
    返回航班;
    }
    int begin=0;
    外部:
    for(int i=0;i
    我修改了“L.Blanc”答案,在开头和结尾处理分隔符。此外,我将其重命名为“split”

    private List<byte[]> split(byte[] array, byte[] delimiter)
    {
       List<byte[]> byteArrays = new LinkedList<byte[]>();
       if (delimiter.length == 0)
       {
          return byteArrays;
       }
       int begin = 0;
    
       outer: for (int i = 0; i < array.length - delimiter.length + 1; i++)
       {
          for (int j = 0; j < delimiter.length; j++)
          {
             if (array[i + j] != delimiter[j])
             {
                continue outer;
             }
          }
    
          // If delimiter is at the beginning then there will not be any data.
          if (begin != i)
             byteArrays.add(Arrays.copyOfRange(array, begin, i));
          begin = i + delimiter.length;
       }
    
       // delimiter at the very end with no data following?
       if (begin != array.length)
          byteArrays.add(Arrays.copyOfRange(array, begin, array.length));
    
       return byteArrays;
    }
    
    私有列表拆分(字节[]数组,字节[]分隔符)
    {
    List ByteArray=新建LinkedList();
    if(delimiter.length==0)
    {
    返回航班;
    }
    int begin=0;
    外部:用于(int i=0;i
    这是对以下答案的一些改进: 假设我们有这样的数组
    | | | | | | aaa | | bbb
    和分隔符
    |
    。在这种情况下,我们得到

    java.lang.IllegalArgumentException: 2 > 1
        at java.util.Arrays.copyOfRange(Arrays.java:3519)
    
    因此,最终改进的解决方案是:

    public static List<byte[]> split(byte[] array, byte[] delimiter) {
            List<byte[]> byteArrays = new LinkedList<>();
            if (delimiter.length == 0) {
                return byteArrays;
            }
            int begin = 0;
    
            outer:
            for (int i = 0; i < array.length - delimiter.length + 1; i++) {
                for (int j = 0; j < delimiter.length; j++) {
                    if (array[i + j] != delimiter[j]) {
                        continue outer;
                    }
                }
    
                // This condition was changed
                if (begin != i)
                    byteArrays.add(Arrays.copyOfRange(array, begin, i));
                begin = i + delimiter.length;
            }
    
            // Also here we may change condition to 'less'
            if (begin < array.length)
                byteArrays.add(Arrays.copyOfRange(array, begin, array.length));
    
            return byteArrays;
        }
    
    公共静态列表拆分(字节[]数组,字节[]分隔符){
    L
    
    public static List<byte[]> split(byte[] array, byte[] delimiter) {
            List<byte[]> byteArrays = new LinkedList<>();
            if (delimiter.length == 0) {
                return byteArrays;
            }
            int begin = 0;
    
            outer:
            for (int i = 0; i < array.length - delimiter.length + 1; i++) {
                for (int j = 0; j < delimiter.length; j++) {
                    if (array[i + j] != delimiter[j]) {
                        continue outer;
                    }
                }
    
                // This condition was changed
                if (begin != i)
                    byteArrays.add(Arrays.copyOfRange(array, begin, i));
                begin = i + delimiter.length;
            }
    
            // Also here we may change condition to 'less'
            if (begin < array.length)
                byteArrays.add(Arrays.copyOfRange(array, begin, array.length));
    
            return byteArrays;
        }