2010-08-04 64 views
9

我想将一个大的字节数组分成更小的数据块(比如64个字节)。请帮我解决一下这个。将数组分成较小的部分

+1

听起来类似于http://stackoverflow.com/questions/3395547/how-to-get-a-sub-array-of-array-in-java-without-copying-data/ – 2010-08-04 12:44:19

回答

14

您可以使用该方法Arrays.copyOfRange(原从,到)

public static byte[][] divideArray(byte[] source, int chunksize) { 


     byte[][] ret = new byte[(int)Math.ceil(source.length/(double)chunksize)][chunksize]; 

     int start = 0; 

     for(int i = 0; i < ret.length; i++) { 
      ret[i] = Arrays.copyOfRange(source,start, start + chunksize); 
      start += chunksize ; 
     } 

     return ret; 
    } 

或者您可以使用如马克斯建议System.arraycopy

public static byte[][] divideArray(byte[] source, int chunksize) { 


     byte[][] ret = new byte[(int)Math.ceil(source.length/(double)chunksize)][chunksize]; 

     int start = 0; 

     for(int i = 0; i < ret.length; i++) { 
      if(start + chunksize > source.length) { 
       System.arraycopy(source, start, ret[i], 0, source.length - start); 
      } else { 
       System.arraycopy(source, start, ret[i], 0, chunksize); 
      } 
      start += chunksize ; 
     } 


     return ret; 
    } 
+0

它对我真的很有帮助。谢谢 – 2012-07-21 07:32:58

+1

请注意,如果source.length不是偶数的偶数倍,那么其中的第二个似乎会分配最后一个块的“太大”... – rogerdpack 2015-05-06 23:45:58

0

Arrays.copyOfRange寻求帮助。你可以在循环中使用它将你的数组拆分成几个更小的块。

2

那么,System.arraycopy(src,fromPos,dest,toPos,length)通常被认为比Arrays.copyOfRange更快。

byte[] source = ...read it from somewhere...; 
byte[] newArray = new byte[64]; 
System.arraycopy(source, 0, newArray, 0, 64); 
+4

这是不正确的:这不是一个更快的问题,'数组。 copyOfRange'也分配一个新的'array',而'System.arraycopy'只是复制另一个'array'中的元素作为参数传递。所以第二个你保存分配..这就是为什么它更快。如果你检查'Array.copyOfRange'的定义,你会看到它调用'System.arraycopy' .. – Jack 2010-08-04 12:41:29

+0

是的,只是检查,你是对的。 – bezmax 2010-08-04 12:54:21

1

你有两个选择:

  • System.arraycopy(...)
  • Array.copyOfRange(...)

两者的工作方式相同,但是当第一个只可管理拷贝,第二个,就是要用于同时分配新块。

我一个结果System.arraycopy为基准,它们更快,如果你管理你的拆分数组,但如果你将它们分配whle复制稍慢之前分配块一起:在这种情况下,你应该使用Array.copyOfRange

+0

Array.copyOfRange()调用System.arraycopy时非常有趣的基准测试:http://pastebin.com/SpSyx8Cd – bezmax 2010-08-04 12:56:10

0

这样做......

byte[] source = new byte[2048]; 
    byte[] target = new byte[1024]; 

// fill source with some data... 

    Array.Copy(source, buffer, 1024); 
9

达米安VASH的第一个方法添加零到最后块结束时,如果输入不是CHUNKSIZE的准确的倍数(使用Arrays.copyOfRange()一) 。

您可能要改用这一点:

public static List<byte[]> divideArray(byte[] source, int chunksize) { 

    List<byte[]> result = new ArrayList<byte[]>(); 
    int start = 0; 
    while (start < source.length) { 
     int end = Math.min(source.length, start + chunksize); 
     result.add(Arrays.copyOfRange(source, start, end)); 
     start += chunksize; 
    } 

    return result; 
} 

,并在情况下,它是非常有用的,使用同样的事情的ArrayList的:

public static List<List<String>> divideList(List<String> source, int chunksize) { 
    List<List<String>> result = new ArrayList<List<String>>(); 
    int start = 0; 
    while (start < source.size()) { 
     int end = Math.min(source.size(), start + chunksize); 
     result.add(source.subList(start, end)); 
     start += chunksize; 
    } 
    return result; 
    } 
3

如果你正在寻找节省一些内存,略有修改达米安瓦什的答案将有所帮助(在这种情况下,任何剩余的块没有分配完整的64字节块大小,以及...)

private byte[][] splitChunks(byte[] source) 
{ 
    byte[][] ret = new byte[(int)Math.ceil(source.length/(double)CHUNK_SIZE)][]; 
    int start = 0; 
    for(int i = 0; i < ret.length; i++) { 
     if(start + CHUNK_SIZE > source.length) { 
      ret[i] = new byte[source.length-start]; 
      System.arraycopy(source, start, ret[i], 0, source.length - start); 
     } 
     else { 
      ret[i] = new byte[CHUNK_SIZE]; 
      System.arraycopy(source, start, ret[i], 0, CHUNK_SIZE); 
     } 
     start += CHUNK_SIZE ; 
    } 
    return ret; 
}