将数组分成较小的部分

14

我想将一个大的字节数组分成小块(比如每64个字节一块)。请帮我实现这个功能。


1
听起来很像https://dev59.com/ZXA75IYBdhLWcg3wP2kg。 - Markus Kull
8个回答

18

Damian Vash的第一种方法(使用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;
  }

如何使用此方法将字节分成 5 MB 的块? - Vishal Patoliya ツ

15

你可以使用Arrays.copyOfRange(original, from, to)方法

 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;
    }

您也可以像Max建议的那样使用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;
    }

2
请注意,如果源长度不是块大小的偶数倍,则第二个似乎会分配“太大”的最后一个块... - rogerdpack
如何使用这个程序将字节分成5 MB的块? - Vishal Patoliya ツ
@VishalPatoliyaツ 只需将块大小设置为5000000字节即可。因为5MB = 500万字节。 - Gaurav Mall

3
如果您想节省一些内存,对Damian Vash的回答进行轻微修改会有所帮助(在这种情况下,任何剩余的块都不会分配完整的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;
}

如何使用这个工具将字节分成5 MB的块? - Vishal Patoliya ツ

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
这是不正确的:问题并不仅在于速度,Arrays.copyOfRange 也会分配一个新的数组,而 System.arraycopy 只是将元素复制到作为参数传递的另一个数组中。因此,使用第二种方法可以节省分配时间... 这就是为什么它更快。如果您检查Array.copyOfRange 的定义,您会发现它调用了 System.arraycopy - Jack

1

你有两个选择:

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

它们两个的工作方式相同,但第一个仅管理复制,而第二个则旨在同时分配新块。

我进行了基准测试,结果表明,如果您在拆分数组之前成功分配所有块,则System.arraycopy更快,但如果您在复制时分配它们,则略慢,此时应使用Array.copyOfRange


非常有趣的基准测试,因为Array.copyOfRange()调用了System.arraycopy:http://pastebin.com/SpSyx8Cd - bezmax

0

这样做就可以了...

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

// fill source with some data...

    Array.Copy(source, buffer, 1024);

0
请参考Arrays.copyOfRange以获取帮助。您可以在循环中使用它将数组分成几个较小的块。

0

这是使用Arrays.copyOfRange将字节数组分成块(将“数据”分成blockSize块)的另一种可能方法:

byte[] data = { 2, 3, 5, 7, 8, 9, 11, 12, 13 };
// Block size in bytes (default: 64k)
int blockSize = 64 * 1024;
int blockCount = (data.length + blockSize - 1) / blockSize;

byte[] range;

try {
  
    for (int i = 1; i < blockCount; i++) {
        int idx = (i - 1) * blockSize;
        range = Arrays.copyOfRange(data, idx, idx + blockSize);
        System.out.println("Chunk " + i + ": " Arrays.toString(range));
    }

} finally {
    
    // Last chunk
    int end = -1;
    if (data.length % blockSize == 0) {
            end = data.length;
    } else {
            end = data.length % blockSize + blockSize * (blockCount - 1);
    }
        
    range = Arrays.copyOfRange(data, (blockCount - 1) * blockSize, end);

    System.out.println("Chunk " + blockCount + ": " Arrays.toString(range));
}

仅包含代码的答案是低质量的答案。 - Taslim Oseni

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