我正在尝试对图像的字节进行“切块(chunk)”。这将允许我分部上传大型图像。目前,我已将图像存储为一个大的byte[]数组。我想将该字节数组拆分为长度不超过512个元素的byte[]
数组。然而,我不确定最有效的方法是什么。
有没有人知道如何以最有效的方式实现这一点?
我正在尝试对图像的字节进行“切块(chunk)”。这将允许我分部上传大型图像。目前,我已将图像存储为一个大的byte[]数组。我想将该字节数组拆分为长度不超过512个元素的byte[]
数组。然而,我不确定最有效的方法是什么。
有没有人知道如何以最有效的方式实现这一点?
我为此编写了一个扩展,最初是针对字符串的,但后来决定将其通用化。
public static T[] CopySlice<T>(this T[] source, int index, int length, bool padToLength = false)
{
int n = length;
T[] slice = null;
if (source.Length < index + length)
{
n = source.Length - index;
if (padToLength)
{
slice = new T[length];
}
}
if(slice == null) slice = new T[n];
Array.Copy(source, index, slice, 0, n);
return slice;
}
public static IEnumerable<T[]> Slices<T>(this T[] source, int count, bool padToLength = false)
{
for (var i = 0; i < source.Length; i += count)
yield return source.CopySlice(i, count, padToLength);
}
byte[] myBytes; // original byte array
foreach(byte[] copySlice in myBytes.Slices(10))
{
// do something with each slice
}
编辑:我在 Stack Overflow 上提供了一个使用 Buffer.BlockCopy 的答案(这里),但是 BlockCopy 只能用于 byte[]
数组,因此无法为字符串创建通用版本。
ArraySegment<T>
的语义。) - CodesInChaosbyte[] myBytes = new byte[33]; foreach (byte[] copySlice in myBytes.Slices(16)) {....}
。 - L.Bbyte[] buffer = new byte[512];
while(true) {
int space = 512, read, offset = 0;
while(space > 0 && (read = stream.Read(buffer, offset, space)) > 0) {
space -= read;
offset += read;
}
// either a full buffer, or EOF
if(space != 0) { // EOF - final
if(offset != 0) { // something to send
Array.Resize(red buffer, offset);
Upload(buffer);
}
break;
} else { // full buffer
Upload(buffer);
}
}
public static IEnumerable<byte[]> Split(this byte[] value,int bufferLength){
int countOfArray = value.Length / bufferLength;
if(value.Length % bufferLength > 0)
countOfArray ++;
for(int i=0;i<countOfArray;i++)
{
yield return value.Skip(i * bufferLength).Take(bufferLength).ToArray();
}
}
这是我使用的扩展程序
private byte[][] ByteArrayToChunks(byte[] byteData, long BufferSize)
{
byte[][] chunks = byteData.Select((value, index) => new { PairNum = Math.Floor(index / (double)BufferSize), value }).GroupBy(pair => pair.PairNum).Select(grp => grp.Select(g => g.value).ToArray()).ToArray();
return chunks;
}
System.Linq
内置了一个用于此目的的Chunk
方法。using System.Linq;
...
byte[] myBytes = new byte[131072];
int myMaxChunkSizeInBytes = 512;
foreach(byte[] chunk in myBytes.Chunk(myMaxChunkSizeInBytes))
{
// do something with each chunk
}
...
微软文档:System.Linq.Enumerable.Chunk(IEnumerable, Int32)