【问题标题】:How do I split a byte[] image into multiple byte[] of a maximum 10000 length each byte?如何将 byte[] 图像拆分为每个字节最大 10000 长度的多个 byte[]?
【发布时间】:2021-08-17 01:52:53
【问题描述】:

我在这里找到了很多答案,但没有一个是我真正想要的。

假设我可以发送最大 10000 大小的图像,因此如果我发送例如 25796 的图像,我需要将 byte[] 拆分为 3、10000 + 10000 + 5796。

所以我想我应该有一个接收 byte[] 并返回列表的方法 对吗?

我在一个循环中使用Arrays.copyOfRange,但最后一个字节很难获得(例如最后的那些 5796)。

希望有人可以帮助我。

非常感谢!

编辑:

我想我已经成功了,我需要测试更多的案例,但是明天我会这样做,因为我累了。如果一切正常,我会将其发布为答案。

这是我现在所拥有的:(有一个额外的方法来检查字节是否匹配)

public List<byte[]> byteSplitter(byte[] origin) {


    List<byte[]> byteList = new LinkedList<>();


    int splitIndex = 10000;
    int currBytes = 0;
    boolean bytesHasSameLength = false;
    while (!bytesHasSameLength) {

        if (splitIndex > origin.length) {
            splitIndex = origin.length;
            bytesHasSameLength = true;
        }

        byteList.add(Arrays.copyOfRange(origin, currBytes, splitIndex));

        currBytes = splitIndex;
        splitIndex += 10000;

    }


    return byteList;
}

public void appendByteAndCheckMatch(byte[] bytes, List<byte[]> byteList) {

    ByteArrayOutputStream output = new ByteArrayOutputStream();

    for (byte[] b : byteList) {
        try {
            output.write(b);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    byte[] bytesFromList = output.toByteArray();

    System.out.println("list bytes: " + bytesFromList.length);
    System.out.println("request bytes: " + bytes.length);

    if (Arrays.equals(bytesFromList, bytes))
        System.out.println("bytes are equals");
    else
        System.out.println("bytes are different");
}

结果:

列表字节:25796 请求字节:25796 字节相等

【问题讨论】:

    标签: java image-processing split byte


    【解决方案1】:

    你可以像这样很容易地做到这一点。结束位置调整为不超过原始大小。

    byte[] array = new byte[123039];
    int bufSize = 10_000;
    int end = 0;
    for (int offset = 0; offset <= array.length; offset+= bufSize) {
        end+=bufSize;
        if (end >= array.length) {
            end = array.length;
        }
        byte[] arr = Arrays.copyOfRange(array, offset, end  );
        // do something with arr
    }
    

    【讨论】:

      【解决方案2】:

      您需要以“最大长度”为增量循环遍历原始数组,同时确保不超过数组的长度。这可以通过一个 for 循环来完成。例如:

      public static List<byte[]> split(byte[] source, int maxLength) {
        Objects.requireNonNull(source);
        if (maxLength <= 0) {
          throw new IllegalArgumentException("maxLength <= 0");
        }
      
        List<byte[]> result = new ArrayList<>();
      
        for (int from = 0; from < source.length; from += maxLength) {
          int to = Math.min(from + maxLength, source.length);
          byte[] range = Arrays.copyOfRange(source, from, to);
          result.add(range);
        }
      
        return result;
      }
      

      这将处理maxLength 的任何非零正值,即使该值大于或等于source 的长度。

      请注意,这是将数据从原始数组复制到新数组中。这意味着原始数组被有效地复制了,这可能是也可能不是可接受的,因为您现在至少消耗了两倍的内存(尽管您可能会丢弃原始数组)。如果您的用例允许,并且您需要使用尽可能少的内存,请考虑使用ByteBuffer

      public static List<ByteBuffer> split(byte[] source, int maxLength) {
        return split(ByteBuffer.wrap(source), maxLength);
      }
      
      public static List<ByteBuffer> split(ByteBuffer source, int maxLength) {
        Objects.requireNonNull(source);
        if (maxLength <= 0) {
          throw new IllegalArgumentException("maxLength <= 0");
        }
      
        List<ByteBuffer> result = new ArrayList<>();
      
        for (int index = source.position(); index < source.limit(); index += maxLength) {
          int length = Math.min(maxLength, source.limit() - index);
          ByteBuffer slice = source.slice(index, length);
          result.add(slice);
        }
      
        return result;
      }
      

      列表中返回的每个ByteBuffer 都使用相同的支持数据。当然,这样做的一个后果是对源数据的更改会影响每个缓冲区。虽然如果您愿意,您可以将缓冲区设置为只读(请记住,如果您包装数组,则直接更改数组也会影响缓冲区,并且您不能将数组设置为只读)。

      【讨论】:

      • 这是一个非常聪明的答案!多谢。经过几次测试后,我解决它的方式完美无缺,但你的方式比我的要好。谢谢!
      • 快速跟进:注意我写的代码,如果source.length == 0source.position() == source.limit(),它将返回一个空列表。如果返回的列表永远不应该为空,您可能需要处理这种情况。
      猜你喜欢
      • 2012-08-02
      • 1970-01-01
      • 2021-04-30
      • 1970-01-01
      • 2015-03-13
      • 2012-08-05
      • 1970-01-01
      • 2019-05-24
      • 1970-01-01
      相关资源
      最近更新 更多