如何将 byte[] 图像拆分为每个字节最大 10000 长度的多个 byte[]?
How do I split a byte[] image into multiple byte[] of a maximum 10000 length each byte?
我在这里找到了很多答案,但其中 none 确实是我想要的。
假设我可以发送最大尺寸为 10000 的图像,因此如果我发送例如 25796 的图像,我需要将 byte[] 拆分为 3、10000 + 10000 + 5796。
所以我想我应该有一个接收字节 [] 和 returns 列表的方法 对吗?
我在循环中使用 Arrays.copyOfRange
,但最后的字节很难获取(例如最后的 5796)。
希望有人能帮助我。
非常感谢!
编辑:
我想我已经成功了,我需要测试更多的案例,但明天我会这样做,因为我很累 rn。如果一切正常,我会 post 作为答案。
这是我现在拥有的:(有一个额外的方法来检查最后字节是否匹配)
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
字节等于
你可以像这样很容易地做到这一点。结束位置调整为不超过原尺寸
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
}
您需要以“最大长度”为增量遍历原始数组,同时还要确保您不会超过数组的长度。这可以通过单个 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
使用相同的支持数据。当然,这样做的一个后果是对源数据的更改会影响每个缓冲区。尽管如果你愿意,你可以将缓冲区设置为只读(请记住,如果你包装一个数组然后直接更改数组也会影响缓冲区,并且你不能将数组设置为只读)。
我在这里找到了很多答案,但其中 none 确实是我想要的。
假设我可以发送最大尺寸为 10000 的图像,因此如果我发送例如 25796 的图像,我需要将 byte[] 拆分为 3、10000 + 10000 + 5796。
所以我想我应该有一个接收字节 [] 和 returns 列表的方法
我在循环中使用 Arrays.copyOfRange
,但最后的字节很难获取(例如最后的 5796)。
希望有人能帮助我。
非常感谢!
编辑:
我想我已经成功了,我需要测试更多的案例,但明天我会这样做,因为我很累 rn。如果一切正常,我会 post 作为答案。
这是我现在拥有的:(有一个额外的方法来检查最后字节是否匹配)
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 字节等于
你可以像这样很容易地做到这一点。结束位置调整为不超过原尺寸
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
}
您需要以“最大长度”为增量遍历原始数组,同时还要确保您不会超过数组的长度。这可以通过单个 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
使用相同的支持数据。当然,这样做的一个后果是对源数据的更改会影响每个缓冲区。尽管如果你愿意,你可以将缓冲区设置为只读(请记住,如果你包装一个数组然后直接更改数组也会影响缓冲区,并且你不能将数组设置为只读)。